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            E::InvalidTransferObject => CommandArgumentErrorKind::InvalidTransferObject,
1222            E::InvalidMakeMoveVecNonObjectArgument => {
1223                CommandArgumentErrorKind::InvalidMakeMoveVecNonObjectArgument
1224            }
1225            E::ArgumentWithoutValue => CommandArgumentErrorKind::ArgumentWithoutValue,
1226            E::CannotMoveBorrowedValue => CommandArgumentErrorKind::CannotMoveBorrowedValue,
1227            E::CannotWriteToExtendedReference => {
1228                CommandArgumentErrorKind::CannotWriteToExtendedReference
1229            }
1230            E::InvalidReferenceArgument => CommandArgumentErrorKind::InvalidReferenceArgument,
1231        };
1232
1233        message.set_kind(kind);
1234        message
1235    }
1236}
1237
1238//
1239// TypeArgumentError
1240//
1241
1242impl From<crate::execution_status::TypeArgumentError>
1243    for type_argument_error::TypeArgumentErrorKind
1244{
1245    fn from(value: crate::execution_status::TypeArgumentError) -> Self {
1246        use crate::execution_status::TypeArgumentError::*;
1247
1248        match value {
1249            TypeNotFound => Self::TypeNotFound,
1250            ConstraintNotSatisfied => Self::ConstraintNotSatisfied,
1251        }
1252    }
1253}
1254
1255//
1256// PackageUpgradeError
1257//
1258
1259impl From<crate::execution_status::PackageUpgradeError> for PackageUpgradeError {
1260    fn from(value: crate::execution_status::PackageUpgradeError) -> Self {
1261        use crate::execution_status::PackageUpgradeError as E;
1262        use package_upgrade_error::PackageUpgradeErrorKind;
1263
1264        let mut message = Self::default();
1265
1266        let kind = match value {
1267            E::UnableToFetchPackage { package_id } => {
1268                message.package_id = Some(package_id.to_canonical_string(true));
1269                PackageUpgradeErrorKind::UnableToFetchPackage
1270            }
1271            E::NotAPackage { object_id } => {
1272                message.package_id = Some(object_id.to_canonical_string(true));
1273                PackageUpgradeErrorKind::NotAPackage
1274            }
1275            E::IncompatibleUpgrade => PackageUpgradeErrorKind::IncompatibleUpgrade,
1276            E::DigestDoesNotMatch { digest } => {
1277                message.digest = crate::digests::Digest::try_from(digest)
1278                    .ok()
1279                    .map(|d| d.to_string());
1280                PackageUpgradeErrorKind::DigestDoesNotMatch
1281            }
1282            E::UnknownUpgradePolicy { policy } => {
1283                message.policy = Some(policy.into());
1284                PackageUpgradeErrorKind::UnknownUpgradePolicy
1285            }
1286            E::PackageIDDoesNotMatch {
1287                package_id,
1288                ticket_id,
1289            } => {
1290                message.package_id = Some(package_id.to_canonical_string(true));
1291                message.ticket_id = Some(ticket_id.to_canonical_string(true));
1292                PackageUpgradeErrorKind::PackageIdDoesNotMatch
1293            }
1294        };
1295
1296        message.set_kind(kind);
1297        message
1298    }
1299}
1300
1301//
1302// MoveLocation
1303//
1304
1305impl From<crate::execution_status::MoveLocation> for MoveLocation {
1306    fn from(value: crate::execution_status::MoveLocation) -> Self {
1307        let mut message = Self::default();
1308        message.package = Some(value.module.address().to_canonical_string(true));
1309        message.module = Some(value.module.name().to_string());
1310        message.function = Some(value.function.into());
1311        message.instruction = Some(value.instruction.into());
1312        message.function_name = value.function_name.map(|name| name.to_string());
1313        message
1314    }
1315}
1316
1317//
1318// AuthorityQuorumSignInfo aka ValidatorAggregatedSignature
1319//
1320
1321impl<const T: bool> From<crate::crypto::AuthorityQuorumSignInfo<T>>
1322    for ValidatorAggregatedSignature
1323{
1324    fn from(value: crate::crypto::AuthorityQuorumSignInfo<T>) -> Self {
1325        let mut bitmap = Vec::new();
1326        value.signers_map.serialize_into(&mut bitmap).unwrap();
1327
1328        Self::default()
1329            .with_epoch(value.epoch)
1330            .with_signature(value.signature.as_ref().to_vec())
1331            .with_bitmap(bitmap)
1332    }
1333}
1334
1335impl<const T: bool> TryFrom<&ValidatorAggregatedSignature>
1336    for crate::crypto::AuthorityQuorumSignInfo<T>
1337{
1338    type Error = TryFromProtoError;
1339
1340    fn try_from(value: &ValidatorAggregatedSignature) -> Result<Self, Self::Error> {
1341        Ok(Self {
1342            epoch: value.epoch(),
1343            signature: crate::crypto::AggregateAuthoritySignature::from_bytes(value.signature())
1344                .map_err(|e| TryFromProtoError::invalid("signature", e))?,
1345            signers_map: crate::sui_serde::deserialize_sui_bitmap(value.bitmap())
1346                .map_err(|e| TryFromProtoError::invalid("bitmap", e))?,
1347        })
1348    }
1349}
1350
1351//
1352// ValidatorCommittee
1353//
1354
1355impl From<crate::committee::Committee> for ValidatorCommittee {
1356    fn from(value: crate::committee::Committee) -> Self {
1357        let mut message = Self::default();
1358        message.epoch = Some(value.epoch);
1359        message.members = value
1360            .voting_rights
1361            .into_iter()
1362            .map(|(name, weight)| {
1363                let mut member = ValidatorCommitteeMember::default();
1364                member.public_key = Some(name.0.to_vec().into());
1365                member.weight = Some(weight);
1366                member
1367            })
1368            .collect();
1369        message
1370    }
1371}
1372
1373//
1374// ZkLoginAuthenticator
1375//
1376
1377impl From<&crate::zk_login_authenticator::ZkLoginAuthenticator> for ZkLoginAuthenticator {
1378    fn from(value: &crate::zk_login_authenticator::ZkLoginAuthenticator) -> Self {
1379        //TODO implement this without going through the sdk type
1380        let mut inputs = ZkLoginInputs::default();
1381        inputs.address_seed = Some(value.inputs.get_address_seed().to_string());
1382        let mut message = Self::default();
1383        message.inputs = Some(inputs);
1384        message.max_epoch = Some(value.get_max_epoch());
1385        message.signature = Some(value.user_signature.clone().into());
1386
1387        sui_sdk_types::ZkLoginAuthenticator::try_from(value.clone())
1388            .map(Into::into)
1389            .ok()
1390            .unwrap_or(message)
1391    }
1392}
1393
1394//
1395// ZkLoginPublicIdentifier
1396//
1397
1398impl From<&crate::crypto::ZkLoginPublicIdentifier> for ZkLoginPublicIdentifier {
1399    fn from(value: &crate::crypto::ZkLoginPublicIdentifier) -> Self {
1400        //TODO implement this without going through the sdk type
1401        sui_sdk_types::ZkLoginPublicIdentifier::try_from(value.to_owned())
1402            .map(|id| (&id).into())
1403            .ok()
1404            .unwrap_or_default()
1405    }
1406}
1407
1408//
1409// SignatureScheme
1410//
1411
1412impl From<crate::crypto::SignatureScheme> for SignatureScheme {
1413    fn from(value: crate::crypto::SignatureScheme) -> Self {
1414        use crate::crypto::SignatureScheme as S;
1415
1416        match value {
1417            S::ED25519 => Self::Ed25519,
1418            S::Secp256k1 => Self::Secp256k1,
1419            S::Secp256r1 => Self::Secp256r1,
1420            S::BLS12381 => Self::Bls12381,
1421            S::MultiSig => Self::Multisig,
1422            S::ZkLoginAuthenticator => Self::Zklogin,
1423            S::PasskeyAuthenticator => Self::Passkey,
1424        }
1425    }
1426}
1427
1428//
1429// SimpleSignature
1430//
1431
1432impl From<crate::crypto::Signature> for SimpleSignature {
1433    fn from(value: crate::crypto::Signature) -> Self {
1434        Self::from(&value)
1435    }
1436}
1437
1438impl From<&crate::crypto::Signature> for SimpleSignature {
1439    fn from(value: &crate::crypto::Signature) -> Self {
1440        let scheme: SignatureScheme = value.scheme().into();
1441        let signature = value.signature_bytes();
1442        let public_key = value.public_key_bytes();
1443
1444        let mut message = Self::default();
1445        message.scheme = Some(scheme.into());
1446        message.signature = Some(signature.to_vec().into());
1447        message.public_key = Some(public_key.to_vec().into());
1448        message
1449    }
1450}
1451
1452//
1453// PasskeyAuthenticator
1454//
1455
1456impl From<&crate::passkey_authenticator::PasskeyAuthenticator> for PasskeyAuthenticator {
1457    fn from(value: &crate::passkey_authenticator::PasskeyAuthenticator) -> Self {
1458        let mut message = Self::default();
1459        message.authenticator_data = Some(value.authenticator_data().to_vec().into());
1460        message.client_data_json = Some(value.client_data_json().to_owned());
1461        message.signature = Some(value.signature().into());
1462        message
1463    }
1464}
1465
1466//
1467// MultisigMemberPublicKey
1468//
1469
1470impl From<&crate::crypto::PublicKey> for MultisigMemberPublicKey {
1471    fn from(value: &crate::crypto::PublicKey) -> Self {
1472        let mut message = Self::default();
1473
1474        match value {
1475            crate::crypto::PublicKey::Ed25519(_)
1476            | crate::crypto::PublicKey::Secp256k1(_)
1477            | crate::crypto::PublicKey::Secp256r1(_)
1478            | crate::crypto::PublicKey::Passkey(_) => {
1479                message.public_key = Some(value.as_ref().to_vec().into());
1480            }
1481            crate::crypto::PublicKey::ZkLogin(z) => {
1482                message.zklogin = Some(z.into());
1483            }
1484        }
1485
1486        message.set_scheme(value.scheme().into());
1487        message
1488    }
1489}
1490
1491//
1492// MultisigCommittee
1493//
1494
1495impl From<&crate::multisig::MultiSigPublicKey> for MultisigCommittee {
1496    fn from(value: &crate::multisig::MultiSigPublicKey) -> Self {
1497        let mut message = Self::default();
1498        message.members = value
1499            .pubkeys()
1500            .iter()
1501            .map(|(pk, weight)| {
1502                let mut member = MultisigMember::default();
1503                member.public_key = Some(pk.into());
1504                member.weight = Some((*weight).into());
1505                member
1506            })
1507            .collect();
1508        message.threshold = Some((*value.threshold()).into());
1509        message
1510    }
1511}
1512
1513impl From<&crate::multisig_legacy::MultiSigPublicKeyLegacy> for MultisigCommittee {
1514    fn from(value: &crate::multisig_legacy::MultiSigPublicKeyLegacy) -> Self {
1515        let mut message = Self::default();
1516        message.members = value
1517            .pubkeys()
1518            .iter()
1519            .map(|(pk, weight)| {
1520                let mut member = MultisigMember::default();
1521                member.public_key = Some(pk.into());
1522                member.weight = Some((*weight).into());
1523                member
1524            })
1525            .collect();
1526        message.threshold = Some((*value.threshold()).into());
1527        message
1528    }
1529}
1530
1531//
1532// MultisigMemberSignature
1533//
1534
1535impl From<&crate::crypto::CompressedSignature> for MultisigMemberSignature {
1536    fn from(value: &crate::crypto::CompressedSignature) -> Self {
1537        let mut message = Self::default();
1538
1539        let scheme = match value {
1540            crate::crypto::CompressedSignature::Ed25519(b) => {
1541                message.signature = Some(b.0.to_vec().into());
1542                SignatureScheme::Ed25519
1543            }
1544            crate::crypto::CompressedSignature::Secp256k1(b) => {
1545                message.signature = Some(b.0.to_vec().into());
1546                SignatureScheme::Secp256k1
1547            }
1548            crate::crypto::CompressedSignature::Secp256r1(b) => {
1549                message.signature = Some(b.0.to_vec().into());
1550                SignatureScheme::Secp256r1
1551            }
1552            crate::crypto::CompressedSignature::ZkLogin(_z) => {
1553                //TODO
1554                SignatureScheme::Zklogin
1555            }
1556            crate::crypto::CompressedSignature::Passkey(_p) => {
1557                //TODO
1558                SignatureScheme::Passkey
1559            }
1560        };
1561
1562        message.set_scheme(scheme);
1563        message
1564    }
1565}
1566
1567//
1568// MultisigAggregatedSignature
1569//
1570
1571impl From<&crate::multisig_legacy::MultiSigLegacy> for MultisigAggregatedSignature {
1572    fn from(value: &crate::multisig_legacy::MultiSigLegacy) -> Self {
1573        let mut legacy_bitmap = Vec::new();
1574        value
1575            .get_bitmap()
1576            .serialize_into(&mut legacy_bitmap)
1577            .unwrap();
1578
1579        Self::default()
1580            .with_signatures(value.get_sigs().iter().map(Into::into).collect())
1581            .with_legacy_bitmap(legacy_bitmap)
1582            .with_committee(value.get_pk())
1583    }
1584}
1585
1586impl From<&crate::multisig::MultiSig> for MultisigAggregatedSignature {
1587    fn from(value: &crate::multisig::MultiSig) -> Self {
1588        let mut message = Self::default();
1589        message.signatures = value.get_sigs().iter().map(Into::into).collect();
1590        message.bitmap = Some(value.get_bitmap().into());
1591        message.committee = Some(value.get_pk().into());
1592        message
1593    }
1594}
1595
1596//
1597// UserSignature
1598//
1599
1600impl From<crate::signature::GenericSignature> for UserSignature {
1601    fn from(value: crate::signature::GenericSignature) -> Self {
1602        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
1603    }
1604}
1605
1606impl Merge<&crate::signature::GenericSignature> for UserSignature {
1607    fn merge(&mut self, source: &crate::signature::GenericSignature, mask: &FieldMaskTree) {
1608        use user_signature::Signature;
1609
1610        if mask.contains(Self::BCS_FIELD) {
1611            let mut bcs = Bcs::from(source.as_ref().to_vec());
1612            bcs.name = Some("UserSignatureBytes".to_owned());
1613            self.bcs = Some(bcs);
1614        }
1615
1616        let scheme = match source {
1617            crate::signature::GenericSignature::MultiSig(multi_sig) => {
1618                if mask.contains(Self::MULTISIG_FIELD) {
1619                    self.signature = Some(Signature::Multisig(multi_sig.into()));
1620                }
1621                SignatureScheme::Multisig
1622            }
1623            crate::signature::GenericSignature::MultiSigLegacy(multi_sig_legacy) => {
1624                if mask.contains(Self::MULTISIG_FIELD) {
1625                    self.signature = Some(Signature::Multisig(multi_sig_legacy.into()));
1626                }
1627                SignatureScheme::Multisig
1628            }
1629            crate::signature::GenericSignature::Signature(signature) => {
1630                let scheme = signature.scheme().into();
1631                if mask.contains(Self::SIMPLE_FIELD) {
1632                    self.signature = Some(Signature::Simple(signature.into()));
1633                }
1634                scheme
1635            }
1636            crate::signature::GenericSignature::ZkLoginAuthenticator(z) => {
1637                if mask.contains(Self::ZKLOGIN_FIELD) {
1638                    self.signature = Some(Signature::Zklogin(z.into()));
1639                }
1640                SignatureScheme::Zklogin
1641            }
1642            crate::signature::GenericSignature::PasskeyAuthenticator(p) => {
1643                if mask.contains(Self::PASSKEY_FIELD) {
1644                    self.signature = Some(Signature::Passkey(p.into()));
1645                }
1646                SignatureScheme::Passkey
1647            }
1648        };
1649
1650        if mask.contains(Self::SCHEME_FIELD) {
1651            self.set_scheme(scheme);
1652        }
1653    }
1654}
1655
1656//
1657// BalanceChange
1658//
1659
1660impl From<crate::balance_change::BalanceChange> for BalanceChange {
1661    fn from(value: crate::balance_change::BalanceChange) -> Self {
1662        let mut message = Self::default();
1663        message.address = Some(value.address.to_string());
1664        message.coin_type = Some(value.coin_type.to_canonical_string(true));
1665        message.amount = Some(value.amount.to_string());
1666        message
1667    }
1668}
1669
1670impl TryFrom<&BalanceChange> for crate::balance_change::BalanceChange {
1671    type Error = TryFromProtoError;
1672
1673    fn try_from(value: &BalanceChange) -> Result<Self, Self::Error> {
1674        Ok(Self {
1675            address: value
1676                .address()
1677                .parse()
1678                .map_err(|e| TryFromProtoError::invalid(BalanceChange::ADDRESS_FIELD, e))?,
1679            coin_type: value
1680                .coin_type()
1681                .parse()
1682                .map_err(|e| TryFromProtoError::invalid(BalanceChange::COIN_TYPE_FIELD, e))?,
1683            amount: value
1684                .amount()
1685                .parse()
1686                .map_err(|e| TryFromProtoError::invalid(BalanceChange::AMOUNT_FIELD, e))?,
1687        })
1688    }
1689}
1690
1691//
1692// Object
1693//
1694
1695pub const PACKAGE_TYPE: &str = "package";
1696
1697impl From<crate::object::Object> for Object {
1698    fn from(value: crate::object::Object) -> Self {
1699        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
1700    }
1701}
1702
1703impl Merge<&crate::object::Object> for Object {
1704    fn merge(&mut self, source: &crate::object::Object, mask: &FieldMaskTree) {
1705        if mask.contains(Self::BCS_FIELD.name) {
1706            let mut bcs = Bcs::serialize(&source).unwrap();
1707            bcs.name = Some("Object".to_owned());
1708            self.bcs = Some(bcs);
1709        }
1710
1711        if mask.contains(Self::DIGEST_FIELD.name) {
1712            self.digest = Some(source.digest().to_string());
1713        }
1714
1715        if mask.contains(Self::OBJECT_ID_FIELD.name) {
1716            self.object_id = Some(source.id().to_canonical_string(true));
1717        }
1718
1719        if mask.contains(Self::VERSION_FIELD.name) {
1720            self.version = Some(source.version().value());
1721        }
1722
1723        if mask.contains(Self::OWNER_FIELD.name) {
1724            self.owner = Some(source.owner().to_owned().into());
1725        }
1726
1727        if mask.contains(Self::PREVIOUS_TRANSACTION_FIELD.name) {
1728            self.previous_transaction = Some(source.previous_transaction.to_string());
1729        }
1730
1731        if mask.contains(Self::STORAGE_REBATE_FIELD.name) {
1732            self.storage_rebate = Some(source.storage_rebate);
1733        }
1734
1735        if mask.contains(Self::BALANCE_FIELD) {
1736            self.balance = source.as_coin_maybe().map(|coin| coin.balance.value());
1737        }
1738
1739        self.merge(&source.data, mask);
1740    }
1741}
1742
1743impl Merge<&crate::object::MoveObject> for Object {
1744    fn merge(&mut self, source: &crate::object::MoveObject, mask: &FieldMaskTree) {
1745        self.object_id = Some(source.id().to_canonical_string(true));
1746        self.version = Some(source.version().value());
1747
1748        if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
1749            self.object_type = Some(source.type_().to_canonical_string(true));
1750        }
1751
1752        if mask.contains(Self::HAS_PUBLIC_TRANSFER_FIELD.name) {
1753            self.has_public_transfer = Some(source.has_public_transfer());
1754        }
1755
1756        if mask.contains(Self::CONTENTS_FIELD.name) {
1757            let mut bcs = Bcs::from(source.contents().to_vec());
1758            bcs.name = Some(source.type_().to_canonical_string(true));
1759            self.contents = Some(bcs);
1760        }
1761    }
1762}
1763
1764impl Merge<&crate::move_package::MovePackage> for Object {
1765    fn merge(&mut self, source: &crate::move_package::MovePackage, mask: &FieldMaskTree) {
1766        self.object_id = Some(source.id().to_canonical_string(true));
1767        self.version = Some(source.version().value());
1768
1769        if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
1770            self.object_type = Some(PACKAGE_TYPE.to_owned());
1771        }
1772
1773        if mask.contains(Self::PACKAGE_FIELD.name) {
1774            let mut package = Package::default();
1775            package.modules = source
1776                .serialized_module_map()
1777                .iter()
1778                .map(|(name, contents)| {
1779                    let mut module = Module::default();
1780                    module.name = Some(name.to_string());
1781                    module.contents = Some(contents.clone().into());
1782                    module
1783                })
1784                .collect();
1785            package.type_origins = source
1786                .type_origin_table()
1787                .clone()
1788                .into_iter()
1789                .map(Into::into)
1790                .collect();
1791            package.linkage = source
1792                .linkage_table()
1793                .iter()
1794                .map(
1795                    |(
1796                        original_id,
1797                        crate::move_package::UpgradeInfo {
1798                            upgraded_id,
1799                            upgraded_version,
1800                        },
1801                    )| {
1802                        let mut linkage = Linkage::default();
1803                        linkage.original_id = Some(original_id.to_canonical_string(true));
1804                        linkage.upgraded_id = Some(upgraded_id.to_canonical_string(true));
1805                        linkage.upgraded_version = Some(upgraded_version.value());
1806                        linkage
1807                    },
1808                )
1809                .collect();
1810
1811            self.package = Some(package);
1812        }
1813    }
1814}
1815
1816impl Merge<&crate::object::Data> for Object {
1817    fn merge(&mut self, source: &crate::object::Data, mask: &FieldMaskTree) {
1818        match source {
1819            crate::object::Data::Move(object) => self.merge(object, mask),
1820            crate::object::Data::Package(package) => self.merge(package, mask),
1821        }
1822    }
1823}
1824
1825//
1826// TypeOrigin
1827//
1828
1829impl From<crate::move_package::TypeOrigin> for TypeOrigin {
1830    fn from(value: crate::move_package::TypeOrigin) -> Self {
1831        let mut message = Self::default();
1832        message.module_name = Some(value.module_name.to_string());
1833        message.datatype_name = Some(value.datatype_name.to_string());
1834        message.package_id = Some(value.package.to_canonical_string(true));
1835        message
1836    }
1837}
1838
1839//
1840// GenesisObject
1841//
1842
1843impl From<crate::transaction::GenesisObject> for Object {
1844    fn from(value: crate::transaction::GenesisObject) -> Self {
1845        let crate::transaction::GenesisObject::RawObject { data, owner } = value;
1846        let mut message = Self::default();
1847        message.owner = Some(owner.into());
1848
1849        message.merge(&data, &FieldMaskTree::new_wildcard());
1850
1851        message
1852    }
1853}
1854
1855//
1856// ObjectReference
1857//
1858
1859pub trait ObjectRefExt {
1860    fn to_proto(self) -> ObjectReference;
1861}
1862
1863pub trait ObjectReferenceExt {
1864    fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error>;
1865}
1866
1867impl ObjectRefExt for crate::base_types::ObjectRef {
1868    fn to_proto(self) -> ObjectReference {
1869        let (object_id, version, digest) = self;
1870        let mut message = ObjectReference::default();
1871        message.object_id = Some(object_id.to_canonical_string(true));
1872        message.version = Some(version.value());
1873        message.digest = Some(digest.to_string());
1874        message
1875    }
1876}
1877
1878impl ObjectReferenceExt for ObjectReference {
1879    fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error> {
1880        use anyhow::Context;
1881
1882        let object_id = self
1883            .object_id_opt()
1884            .ok_or_else(|| anyhow::anyhow!("missing object_id"))?;
1885        let object_id = crate::base_types::ObjectID::from_hex_literal(object_id)
1886            .with_context(|| format!("Failed to parse object_id: {}", object_id))?;
1887
1888        let version = self
1889            .version_opt()
1890            .ok_or_else(|| anyhow::anyhow!("missing version"))?;
1891        let version = crate::base_types::SequenceNumber::from(version);
1892
1893        let digest = self
1894            .digest_opt()
1895            .ok_or_else(|| anyhow::anyhow!("missing digest"))?;
1896        let digest = digest
1897            .parse::<crate::digests::ObjectDigest>()
1898            .with_context(|| format!("Failed to parse digest: {}", digest))?;
1899
1900        Ok((object_id, version, digest))
1901    }
1902}
1903
1904impl From<&crate::storage::ObjectKey> for ObjectReference {
1905    fn from(value: &crate::storage::ObjectKey) -> Self {
1906        Self::default()
1907            .with_object_id(value.0.to_canonical_string(true))
1908            .with_version(value.1.value())
1909    }
1910}
1911
1912//
1913// Owner
1914//
1915
1916impl From<crate::object::Owner> for Owner {
1917    fn from(value: crate::object::Owner) -> Self {
1918        use crate::object::Owner as O;
1919        use owner::OwnerKind;
1920
1921        let mut message = Self::default();
1922
1923        let kind = match value {
1924            O::AddressOwner(address) => {
1925                message.address = Some(address.to_string());
1926                OwnerKind::Address
1927            }
1928            O::ObjectOwner(address) => {
1929                message.address = Some(address.to_string());
1930                OwnerKind::Object
1931            }
1932            O::Shared {
1933                initial_shared_version,
1934            } => {
1935                message.version = Some(initial_shared_version.value());
1936                OwnerKind::Shared
1937            }
1938            O::Immutable => OwnerKind::Immutable,
1939            O::ConsensusAddressOwner {
1940                start_version,
1941                owner,
1942            } => {
1943                message.version = Some(start_version.value());
1944                message.address = Some(owner.to_string());
1945                OwnerKind::ConsensusAddress
1946            }
1947        };
1948
1949        message.set_kind(kind);
1950        message
1951    }
1952}
1953
1954//
1955// Transaction
1956//
1957
1958impl From<crate::transaction::TransactionData> for Transaction {
1959    fn from(value: crate::transaction::TransactionData) -> Self {
1960        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
1961    }
1962}
1963
1964impl Merge<&crate::transaction::TransactionData> for Transaction {
1965    fn merge(&mut self, source: &crate::transaction::TransactionData, mask: &FieldMaskTree) {
1966        if mask.contains(Self::BCS_FIELD.name) {
1967            let mut bcs = Bcs::serialize(&source).unwrap();
1968            bcs.name = Some("TransactionData".to_owned());
1969            self.bcs = Some(bcs);
1970        }
1971
1972        if mask.contains(Self::DIGEST_FIELD.name) {
1973            self.digest = Some(source.digest().to_string());
1974        }
1975
1976        if mask.contains(Self::VERSION_FIELD.name) {
1977            self.version = Some(1);
1978        }
1979
1980        let crate::transaction::TransactionData::V1(source) = source;
1981
1982        if mask.contains(Self::KIND_FIELD.name) {
1983            self.kind = Some(source.kind.clone().into());
1984        }
1985
1986        if mask.contains(Self::SENDER_FIELD.name) {
1987            self.sender = Some(source.sender.to_string());
1988        }
1989
1990        if mask.contains(Self::GAS_PAYMENT_FIELD.name) {
1991            self.gas_payment = Some((&source.gas_data).into());
1992        }
1993
1994        if mask.contains(Self::EXPIRATION_FIELD.name) {
1995            self.expiration = Some(source.expiration.into());
1996        }
1997    }
1998}
1999
2000//
2001// GasPayment
2002//
2003
2004impl From<&crate::transaction::GasData> for GasPayment {
2005    fn from(value: &crate::transaction::GasData) -> Self {
2006        let mut message = Self::default();
2007        message.objects = value
2008            .payment
2009            .iter()
2010            .map(|obj_ref| obj_ref.to_proto())
2011            .collect();
2012        message.owner = Some(value.owner.to_string());
2013        message.price = Some(value.price);
2014        message.budget = Some(value.budget);
2015        message
2016    }
2017}
2018
2019//
2020// TransactionExpiration
2021//
2022
2023impl From<crate::transaction::TransactionExpiration> for TransactionExpiration {
2024    fn from(value: crate::transaction::TransactionExpiration) -> Self {
2025        use crate::transaction::TransactionExpiration as E;
2026        use transaction_expiration::TransactionExpirationKind;
2027
2028        let mut message = Self::default();
2029
2030        let kind = match value {
2031            E::None => TransactionExpirationKind::None,
2032            E::Epoch(epoch) => {
2033                message.epoch = Some(epoch);
2034                TransactionExpirationKind::Epoch
2035            }
2036            E::ValidDuring { .. } => {
2037                // TODO: Implement proper proto conversion for ValidDuring
2038                // For now, treat as None to maintain compatibility
2039                TransactionExpirationKind::None
2040            }
2041        };
2042
2043        message.set_kind(kind);
2044        message
2045    }
2046}
2047
2048impl TryFrom<&TransactionExpiration> for crate::transaction::TransactionExpiration {
2049    type Error = &'static str;
2050
2051    fn try_from(value: &TransactionExpiration) -> Result<Self, Self::Error> {
2052        use transaction_expiration::TransactionExpirationKind;
2053
2054        Ok(match value.kind() {
2055            TransactionExpirationKind::None => Self::None,
2056            TransactionExpirationKind::Epoch => Self::Epoch(value.epoch()),
2057            TransactionExpirationKind::Unknown | _ => {
2058                return Err("unknown TransactionExpirationKind");
2059            }
2060        })
2061    }
2062}
2063
2064//
2065// TransactionKind
2066//
2067
2068impl From<crate::transaction::TransactionKind> for TransactionKind {
2069    fn from(value: crate::transaction::TransactionKind) -> Self {
2070        use crate::transaction::TransactionKind as K;
2071        use transaction_kind::Kind;
2072
2073        let message = Self::default();
2074
2075        match value {
2076            K::ProgrammableTransaction(ptb) => message
2077                .with_programmable_transaction(ptb)
2078                .with_kind(Kind::ProgrammableTransaction),
2079            K::ChangeEpoch(change_epoch) => message
2080                .with_change_epoch(change_epoch)
2081                .with_kind(Kind::ChangeEpoch),
2082            K::Genesis(genesis) => message.with_genesis(genesis).with_kind(Kind::Genesis),
2083            K::ConsensusCommitPrologue(prologue) => message
2084                .with_consensus_commit_prologue(prologue)
2085                .with_kind(Kind::ConsensusCommitPrologueV1),
2086            K::AuthenticatorStateUpdate(update) => message
2087                .with_authenticator_state_update(update)
2088                .with_kind(Kind::AuthenticatorStateUpdate),
2089            K::EndOfEpochTransaction(transactions) => message
2090                .with_end_of_epoch({
2091                    EndOfEpochTransaction::default()
2092                        .with_transactions(transactions.into_iter().map(Into::into).collect())
2093                })
2094                .with_kind(Kind::EndOfEpoch),
2095            K::RandomnessStateUpdate(update) => message
2096                .with_randomness_state_update(update)
2097                .with_kind(Kind::RandomnessStateUpdate),
2098            K::ConsensusCommitPrologueV2(prologue) => message
2099                .with_consensus_commit_prologue(prologue)
2100                .with_kind(Kind::ConsensusCommitPrologueV2),
2101            K::ConsensusCommitPrologueV3(prologue) => message
2102                .with_consensus_commit_prologue(prologue)
2103                .with_kind(Kind::ConsensusCommitPrologueV3),
2104            K::ConsensusCommitPrologueV4(prologue) => message
2105                .with_consensus_commit_prologue(prologue)
2106                .with_kind(Kind::ConsensusCommitPrologueV4),
2107            K::ProgrammableSystemTransaction(_) => message,
2108            // TODO support ProgrammableSystemTransaction
2109            // .with_programmable_transaction(ptb)
2110            // .with_kind(Kind::ProgrammableSystemTransaction),
2111        }
2112    }
2113}
2114
2115//
2116// ConsensusCommitPrologue
2117//
2118
2119impl From<crate::messages_consensus::ConsensusCommitPrologue> for ConsensusCommitPrologue {
2120    fn from(value: crate::messages_consensus::ConsensusCommitPrologue) -> Self {
2121        let mut message = Self::default();
2122        message.epoch = Some(value.epoch);
2123        message.round = Some(value.round);
2124        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2125            value.commit_timestamp_ms,
2126        ));
2127        message
2128    }
2129}
2130
2131impl From<crate::messages_consensus::ConsensusCommitPrologueV2> for ConsensusCommitPrologue {
2132    fn from(value: crate::messages_consensus::ConsensusCommitPrologueV2) -> Self {
2133        let mut message = Self::default();
2134        message.epoch = Some(value.epoch);
2135        message.round = Some(value.round);
2136        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2137            value.commit_timestamp_ms,
2138        ));
2139        message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2140        message
2141    }
2142}
2143
2144impl From<crate::messages_consensus::ConsensusCommitPrologueV3> for ConsensusCommitPrologue {
2145    fn from(value: crate::messages_consensus::ConsensusCommitPrologueV3) -> Self {
2146        let mut message = Self::default();
2147        message.epoch = Some(value.epoch);
2148        message.round = Some(value.round);
2149        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2150            value.commit_timestamp_ms,
2151        ));
2152        message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2153        message.sub_dag_index = value.sub_dag_index;
2154        message.consensus_determined_version_assignments =
2155            Some(value.consensus_determined_version_assignments.into());
2156        message
2157    }
2158}
2159
2160impl From<crate::messages_consensus::ConsensusCommitPrologueV4> for ConsensusCommitPrologue {
2161    fn from(
2162        crate::messages_consensus::ConsensusCommitPrologueV4 {
2163            epoch,
2164            round,
2165            sub_dag_index,
2166            commit_timestamp_ms,
2167            consensus_commit_digest,
2168            consensus_determined_version_assignments,
2169            additional_state_digest,
2170        }: crate::messages_consensus::ConsensusCommitPrologueV4,
2171    ) -> Self {
2172        let mut message = Self::default();
2173        message.epoch = Some(epoch);
2174        message.round = Some(round);
2175        message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(commit_timestamp_ms));
2176        message.consensus_commit_digest = Some(consensus_commit_digest.to_string());
2177        message.sub_dag_index = sub_dag_index;
2178        message.consensus_determined_version_assignments =
2179            Some(consensus_determined_version_assignments.into());
2180        message.additional_state_digest = Some(additional_state_digest.to_string());
2181        message
2182    }
2183}
2184
2185//
2186// ConsensusDeterminedVersionAssignments
2187//
2188
2189impl From<crate::messages_consensus::ConsensusDeterminedVersionAssignments>
2190    for ConsensusDeterminedVersionAssignments
2191{
2192    fn from(value: crate::messages_consensus::ConsensusDeterminedVersionAssignments) -> Self {
2193        use crate::messages_consensus::ConsensusDeterminedVersionAssignments as A;
2194
2195        let mut message = Self::default();
2196
2197        let version = match value {
2198            A::CancelledTransactions(canceled_transactions) => {
2199                message.canceled_transactions = canceled_transactions
2200                    .into_iter()
2201                    .map(|(tx_digest, assignments)| {
2202                        let mut message = CanceledTransaction::default();
2203                        message.digest = Some(tx_digest.to_string());
2204                        message.version_assignments = assignments
2205                            .into_iter()
2206                            .map(|(id, version)| {
2207                                let mut message = VersionAssignment::default();
2208                                message.object_id = Some(id.to_canonical_string(true));
2209                                message.version = Some(version.value());
2210                                message
2211                            })
2212                            .collect();
2213                        message
2214                    })
2215                    .collect();
2216                1
2217            }
2218            A::CancelledTransactionsV2(canceled_transactions) => {
2219                message.canceled_transactions = canceled_transactions
2220                    .into_iter()
2221                    .map(|(tx_digest, assignments)| {
2222                        let mut message = CanceledTransaction::default();
2223                        message.digest = Some(tx_digest.to_string());
2224                        message.version_assignments = assignments
2225                            .into_iter()
2226                            .map(|((id, start_version), version)| {
2227                                let mut message = VersionAssignment::default();
2228                                message.object_id = Some(id.to_canonical_string(true));
2229                                message.start_version = Some(start_version.value());
2230                                message.version = Some(version.value());
2231                                message
2232                            })
2233                            .collect();
2234                        message
2235                    })
2236                    .collect();
2237                2
2238            }
2239        };
2240
2241        message.version = Some(version);
2242        message
2243    }
2244}
2245
2246//
2247// GenesisTransaction
2248//
2249
2250impl From<crate::transaction::GenesisTransaction> for GenesisTransaction {
2251    fn from(value: crate::transaction::GenesisTransaction) -> Self {
2252        let mut message = Self::default();
2253        message.objects = value.objects.into_iter().map(Into::into).collect();
2254        message
2255    }
2256}
2257
2258//
2259// RandomnessStateUpdate
2260//
2261
2262impl From<crate::transaction::RandomnessStateUpdate> for RandomnessStateUpdate {
2263    fn from(value: crate::transaction::RandomnessStateUpdate) -> Self {
2264        let mut message = Self::default();
2265        message.epoch = Some(value.epoch);
2266        message.randomness_round = Some(value.randomness_round.0);
2267        message.random_bytes = Some(value.random_bytes.into());
2268        message.randomness_object_initial_shared_version =
2269            Some(value.randomness_obj_initial_shared_version.value());
2270        message
2271    }
2272}
2273
2274//
2275// AuthenticatorStateUpdate
2276//
2277
2278impl From<crate::transaction::AuthenticatorStateUpdate> for AuthenticatorStateUpdate {
2279    fn from(value: crate::transaction::AuthenticatorStateUpdate) -> Self {
2280        let mut message = Self::default();
2281        message.epoch = Some(value.epoch);
2282        message.round = Some(value.round);
2283        message.new_active_jwks = value.new_active_jwks.into_iter().map(Into::into).collect();
2284        message.authenticator_object_initial_shared_version =
2285            Some(value.authenticator_obj_initial_shared_version.value());
2286        message
2287    }
2288}
2289
2290//
2291// ActiveJwk
2292//
2293
2294impl From<crate::authenticator_state::ActiveJwk> for ActiveJwk {
2295    fn from(value: crate::authenticator_state::ActiveJwk) -> Self {
2296        let mut jwk_id = JwkId::default();
2297        jwk_id.iss = Some(value.jwk_id.iss);
2298        jwk_id.kid = Some(value.jwk_id.kid);
2299
2300        let mut jwk = Jwk::default();
2301        jwk.kty = Some(value.jwk.kty);
2302        jwk.e = Some(value.jwk.e);
2303        jwk.n = Some(value.jwk.n);
2304        jwk.alg = Some(value.jwk.alg);
2305
2306        let mut message = Self::default();
2307        message.id = Some(jwk_id);
2308        message.jwk = Some(jwk);
2309        message.epoch = Some(value.epoch);
2310        message
2311    }
2312}
2313
2314//
2315// ChangeEpoch
2316//
2317
2318impl From<crate::transaction::ChangeEpoch> for ChangeEpoch {
2319    fn from(value: crate::transaction::ChangeEpoch) -> Self {
2320        let mut message = Self::default();
2321        message.epoch = Some(value.epoch);
2322        message.protocol_version = Some(value.protocol_version.as_u64());
2323        message.storage_charge = Some(value.storage_charge);
2324        message.computation_charge = Some(value.computation_charge);
2325        message.storage_rebate = Some(value.storage_rebate);
2326        message.non_refundable_storage_fee = Some(value.non_refundable_storage_fee);
2327        message.epoch_start_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2328            value.epoch_start_timestamp_ms,
2329        ));
2330        message.system_packages = value
2331            .system_packages
2332            .into_iter()
2333            .map(|(version, modules, dependencies)| {
2334                let mut message = SystemPackage::default();
2335                message.version = Some(version.value());
2336                message.modules = modules.into_iter().map(Into::into).collect();
2337                message.dependencies = dependencies
2338                    .iter()
2339                    .map(|d| d.to_canonical_string(true))
2340                    .collect();
2341                message
2342            })
2343            .collect();
2344        message
2345    }
2346}
2347
2348//
2349// EndOfEpochTransactionkind
2350//
2351
2352impl From<crate::transaction::EndOfEpochTransactionKind> for EndOfEpochTransactionKind {
2353    fn from(value: crate::transaction::EndOfEpochTransactionKind) -> Self {
2354        use crate::transaction::EndOfEpochTransactionKind as K;
2355        use end_of_epoch_transaction_kind::Kind;
2356
2357        let message = Self::default();
2358
2359        match value {
2360            K::ChangeEpoch(change_epoch) => message
2361                .with_change_epoch(change_epoch)
2362                .with_kind(Kind::ChangeEpoch),
2363            K::AuthenticatorStateCreate => message.with_kind(Kind::AuthenticatorStateCreate),
2364            K::AuthenticatorStateExpire(expire) => message
2365                .with_authenticator_state_expire(expire)
2366                .with_kind(Kind::AuthenticatorStateExpire),
2367            K::RandomnessStateCreate => message.with_kind(Kind::RandomnessStateCreate),
2368            K::DenyListStateCreate => message.with_kind(Kind::DenyListStateCreate),
2369            K::BridgeStateCreate(chain_id) => message
2370                .with_bridge_chain_id(chain_id.to_string())
2371                .with_kind(Kind::BridgeStateCreate),
2372            K::BridgeCommitteeInit(bridge_object_version) => message
2373                .with_bridge_object_version(bridge_object_version.into())
2374                .with_kind(Kind::BridgeCommitteeInit),
2375            K::StoreExecutionTimeObservations(observations) => message
2376                .with_execution_time_observations(observations)
2377                .with_kind(Kind::StoreExecutionTimeObservations),
2378            K::AccumulatorRootCreate => message.with_kind(Kind::AccumulatorRootCreate),
2379            K::CoinRegistryCreate => message.with_kind(Kind::CoinRegistryCreate),
2380            K::DisplayRegistryCreate => message.with_kind(Kind::DisplayRegistryCreate),
2381        }
2382    }
2383}
2384
2385//
2386// AuthenticatorStateExpire
2387//
2388
2389impl From<crate::transaction::AuthenticatorStateExpire> for AuthenticatorStateExpire {
2390    fn from(value: crate::transaction::AuthenticatorStateExpire) -> Self {
2391        let mut message = Self::default();
2392        message.min_epoch = Some(value.min_epoch);
2393        message.authenticator_object_initial_shared_version =
2394            Some(value.authenticator_obj_initial_shared_version.value());
2395        message
2396    }
2397}
2398
2399// ExecutionTimeObservations
2400
2401impl From<crate::transaction::StoredExecutionTimeObservations> for ExecutionTimeObservations {
2402    fn from(value: crate::transaction::StoredExecutionTimeObservations) -> Self {
2403        let mut message = Self::default();
2404        match value {
2405            crate::transaction::StoredExecutionTimeObservations::V1(vec) => {
2406                message.version = Some(1);
2407                message.observations = vec
2408                    .into_iter()
2409                    .map(|(key, observation)| {
2410                        use crate::execution::ExecutionTimeObservationKey as K;
2411                        use execution_time_observation::ExecutionTimeObservationKind;
2412
2413                        let mut message = ExecutionTimeObservation::default();
2414
2415                        let kind = match key {
2416                            K::MoveEntryPoint {
2417                                package,
2418                                module,
2419                                function,
2420                                type_arguments,
2421                            } => {
2422                                message.move_entry_point = Some({
2423                                    let mut message = MoveCall::default();
2424                                    message.package = Some(package.to_canonical_string(true));
2425                                    message.module = Some(module);
2426                                    message.function = Some(function);
2427                                    message.type_arguments = type_arguments
2428                                        .into_iter()
2429                                        .map(|ty| ty.to_canonical_string(true))
2430                                        .collect();
2431                                    message
2432                                });
2433                                ExecutionTimeObservationKind::MoveEntryPoint
2434                            }
2435                            K::TransferObjects => ExecutionTimeObservationKind::TransferObjects,
2436                            K::SplitCoins => ExecutionTimeObservationKind::SplitCoins,
2437                            K::MergeCoins => ExecutionTimeObservationKind::MergeCoins,
2438                            K::Publish => ExecutionTimeObservationKind::Publish,
2439                            K::MakeMoveVec => ExecutionTimeObservationKind::MakeMoveVector,
2440                            K::Upgrade => ExecutionTimeObservationKind::Upgrade,
2441                        };
2442
2443                        message.validator_observations = observation
2444                            .into_iter()
2445                            .map(|(name, duration)| {
2446                                let mut message = ValidatorExecutionTimeObservation::default();
2447                                message.validator = Some(name.0.to_vec().into());
2448                                message.duration = Some(prost_types::Duration {
2449                                    seconds: duration.as_secs() as i64,
2450                                    nanos: duration.subsec_nanos() as i32,
2451                                });
2452                                message
2453                            })
2454                            .collect();
2455
2456                        message.set_kind(kind);
2457                        message
2458                    })
2459                    .collect();
2460            }
2461        }
2462
2463        message
2464    }
2465}
2466
2467//
2468// ProgrammableTransaction
2469//
2470
2471impl From<crate::transaction::ProgrammableTransaction> for ProgrammableTransaction {
2472    fn from(value: crate::transaction::ProgrammableTransaction) -> Self {
2473        let mut message = Self::default();
2474        message.inputs = value.inputs.into_iter().map(Into::into).collect();
2475        message.commands = value.commands.into_iter().map(Into::into).collect();
2476        message
2477    }
2478}
2479
2480//
2481// Input
2482//
2483
2484impl From<crate::transaction::CallArg> for Input {
2485    fn from(value: crate::transaction::CallArg) -> Self {
2486        use crate::transaction::CallArg as I;
2487        use crate::transaction::ObjectArg as O;
2488        use input::InputKind;
2489
2490        let mut message = Self::default();
2491
2492        let kind = match value {
2493            I::Pure(value) => {
2494                message.pure = Some(value.into());
2495                InputKind::Pure
2496            }
2497            I::Object(o) => match o {
2498                O::ImmOrOwnedObject((id, version, digest)) => {
2499                    message.object_id = Some(id.to_canonical_string(true));
2500                    message.version = Some(version.value());
2501                    message.digest = Some(digest.to_string());
2502                    InputKind::ImmutableOrOwned
2503                }
2504                O::SharedObject {
2505                    id,
2506                    initial_shared_version,
2507                    mutability,
2508                } => {
2509                    // TODO(address-balances): add full enum to schema
2510                    message.object_id = Some(id.to_canonical_string(true));
2511                    message.version = Some(initial_shared_version.value());
2512                    message.mutable = Some(mutability.is_exclusive());
2513                    InputKind::Shared
2514                }
2515                O::Receiving((id, version, digest)) => {
2516                    message.object_id = Some(id.to_canonical_string(true));
2517                    message.version = Some(version.value());
2518                    message.digest = Some(digest.to_string());
2519                    InputKind::Receiving
2520                }
2521            },
2522            //TODO
2523            I::FundsWithdrawal(_) => InputKind::Unknown,
2524        };
2525
2526        message.set_kind(kind);
2527        message
2528    }
2529}
2530
2531//
2532// Argument
2533//
2534
2535impl From<crate::transaction::Argument> for Argument {
2536    fn from(value: crate::transaction::Argument) -> Self {
2537        use crate::transaction::Argument as A;
2538        use argument::ArgumentKind;
2539
2540        let mut message = Self::default();
2541
2542        let kind = match value {
2543            A::GasCoin => ArgumentKind::Gas,
2544            A::Input(input) => {
2545                message.input = Some(input.into());
2546                ArgumentKind::Input
2547            }
2548            A::Result(result) => {
2549                message.result = Some(result.into());
2550                ArgumentKind::Result
2551            }
2552            A::NestedResult(result, subresult) => {
2553                message.result = Some(result.into());
2554                message.subresult = Some(subresult.into());
2555                ArgumentKind::Result
2556            }
2557        };
2558
2559        message.set_kind(kind);
2560        message
2561    }
2562}
2563
2564//
2565// Command
2566//
2567
2568impl From<crate::transaction::Command> for Command {
2569    fn from(value: crate::transaction::Command) -> Self {
2570        use crate::transaction::Command as C;
2571        use command::Command;
2572
2573        let command = match value {
2574            C::MoveCall(move_call) => Command::MoveCall((*move_call).into()),
2575            C::TransferObjects(objects, address) => Command::TransferObjects({
2576                let mut message = TransferObjects::default();
2577                message.objects = objects.into_iter().map(Into::into).collect();
2578                message.address = Some(address.into());
2579                message
2580            }),
2581            C::SplitCoins(coin, amounts) => Command::SplitCoins({
2582                let mut message = SplitCoins::default();
2583                message.coin = Some(coin.into());
2584                message.amounts = amounts.into_iter().map(Into::into).collect();
2585                message
2586            }),
2587            C::MergeCoins(coin, coins_to_merge) => Command::MergeCoins({
2588                let mut message = MergeCoins::default();
2589                message.coin = Some(coin.into());
2590                message.coins_to_merge = coins_to_merge.into_iter().map(Into::into).collect();
2591                message
2592            }),
2593            C::Publish(modules, dependencies) => Command::Publish({
2594                let mut message = Publish::default();
2595                message.modules = modules.into_iter().map(Into::into).collect();
2596                message.dependencies = dependencies
2597                    .iter()
2598                    .map(|d| d.to_canonical_string(true))
2599                    .collect();
2600                message
2601            }),
2602            C::MakeMoveVec(element_type, elements) => Command::MakeMoveVector({
2603                let mut message = MakeMoveVector::default();
2604                message.element_type = element_type.map(|t| t.to_canonical_string(true));
2605                message.elements = elements.into_iter().map(Into::into).collect();
2606                message
2607            }),
2608            C::Upgrade(modules, dependencies, package, ticket) => Command::Upgrade({
2609                let mut message = Upgrade::default();
2610                message.modules = modules.into_iter().map(Into::into).collect();
2611                message.dependencies = dependencies
2612                    .iter()
2613                    .map(|d| d.to_canonical_string(true))
2614                    .collect();
2615                message.package = Some(package.to_canonical_string(true));
2616                message.ticket = Some(ticket.into());
2617                message
2618            }),
2619        };
2620
2621        let mut message = Self::default();
2622        message.command = Some(command);
2623        message
2624    }
2625}
2626
2627//
2628// MoveCall
2629//
2630
2631impl From<crate::transaction::ProgrammableMoveCall> for MoveCall {
2632    fn from(value: crate::transaction::ProgrammableMoveCall) -> Self {
2633        let mut message = Self::default();
2634        message.package = Some(value.package.to_canonical_string(true));
2635        message.module = Some(value.module.to_string());
2636        message.function = Some(value.function.to_string());
2637        message.type_arguments = value
2638            .type_arguments
2639            .iter()
2640            .map(|t| t.to_canonical_string(true))
2641            .collect();
2642        message.arguments = value.arguments.into_iter().map(Into::into).collect();
2643        message
2644    }
2645}
2646
2647//
2648// TransactionEffects
2649//
2650
2651impl From<crate::effects::TransactionEffects> for TransactionEffects {
2652    fn from(value: crate::effects::TransactionEffects) -> Self {
2653        Self::merge_from(&value, &FieldMaskTree::new_wildcard())
2654    }
2655}
2656
2657impl Merge<&crate::effects::TransactionEffects> for TransactionEffects {
2658    fn merge(&mut self, source: &crate::effects::TransactionEffects, mask: &FieldMaskTree) {
2659        if mask.contains(Self::BCS_FIELD.name) {
2660            let mut bcs = Bcs::serialize(&source).unwrap();
2661            bcs.name = Some("TransactionEffects".to_owned());
2662            self.bcs = Some(bcs);
2663        }
2664
2665        if mask.contains(Self::DIGEST_FIELD.name) {
2666            self.digest = Some(source.digest().to_string());
2667        }
2668
2669        match source {
2670            crate::effects::TransactionEffects::V1(v1) => self.merge(v1, mask),
2671            crate::effects::TransactionEffects::V2(v2) => self.merge(v2, mask),
2672        }
2673    }
2674}
2675
2676//
2677// TransactionEffectsV1
2678//
2679
2680impl Merge<&crate::effects::TransactionEffectsV1> for TransactionEffects {
2681    fn merge(&mut self, value: &crate::effects::TransactionEffectsV1, mask: &FieldMaskTree) {
2682        use crate::effects::TransactionEffectsAPI;
2683
2684        if mask.contains(Self::VERSION_FIELD.name) {
2685            self.version = Some(1);
2686        }
2687
2688        if mask.contains(Self::STATUS_FIELD.name) {
2689            self.status = Some(value.status().clone().into());
2690        }
2691
2692        if mask.contains(Self::EPOCH_FIELD.name) {
2693            self.epoch = Some(value.executed_epoch());
2694        }
2695
2696        if mask.contains(Self::GAS_USED_FIELD.name) {
2697            self.gas_used = Some(value.gas_cost_summary().clone().into());
2698        }
2699
2700        if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
2701            self.transaction_digest = Some(value.transaction_digest().to_string());
2702        }
2703
2704        if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
2705            self.events_digest = value.events_digest().map(|d| d.to_string());
2706        }
2707
2708        if mask.contains(Self::DEPENDENCIES_FIELD.name) {
2709            self.dependencies = value
2710                .dependencies()
2711                .iter()
2712                .map(ToString::to_string)
2713                .collect();
2714        }
2715
2716        if mask.contains(Self::CHANGED_OBJECTS_FIELD.name)
2717            || mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name)
2718            || mask.contains(Self::GAS_OBJECT_FIELD.name)
2719        {
2720            let mut changed_objects = Vec::new();
2721            let mut unchanged_consensus_objects = Vec::new();
2722
2723            for ((id, version, digest), owner) in value.created() {
2724                let mut change = ChangedObject::default();
2725                change.object_id = Some(id.to_canonical_string(true));
2726                change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
2727                change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
2728                change.output_version = Some(version.value());
2729                change.output_digest = Some(digest.to_string());
2730                change.output_owner = Some(owner.clone().into());
2731                change.id_operation = Some(changed_object::IdOperation::Created.into());
2732
2733                changed_objects.push(change);
2734            }
2735
2736            for ((id, version, digest), owner) in value.mutated() {
2737                let mut change = ChangedObject::default();
2738                change.object_id = Some(id.to_canonical_string(true));
2739                change.input_state = Some(changed_object::InputObjectState::Exists.into());
2740                change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
2741                change.output_version = Some(version.value());
2742                change.output_digest = Some(digest.to_string());
2743                change.output_owner = Some(owner.clone().into());
2744                change.id_operation = Some(changed_object::IdOperation::None.into());
2745
2746                changed_objects.push(change);
2747            }
2748
2749            for ((id, version, digest), owner) in value.unwrapped() {
2750                let mut change = ChangedObject::default();
2751                change.object_id = Some(id.to_canonical_string(true));
2752                change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
2753                change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
2754                change.output_version = Some(version.value());
2755                change.output_digest = Some(digest.to_string());
2756                change.output_owner = Some(owner.clone().into());
2757                change.id_operation = Some(changed_object::IdOperation::None.into());
2758
2759                changed_objects.push(change);
2760            }
2761
2762            for (id, version, digest) in value.deleted() {
2763                let mut change = ChangedObject::default();
2764                change.object_id = Some(id.to_canonical_string(true));
2765                change.input_state = Some(changed_object::InputObjectState::Exists.into());
2766                change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
2767                change.output_version = Some(version.value());
2768                change.output_digest = Some(digest.to_string());
2769                change.id_operation = Some(changed_object::IdOperation::Deleted.into());
2770
2771                changed_objects.push(change);
2772            }
2773
2774            for (id, version, digest) in value.unwrapped_then_deleted() {
2775                let mut change = ChangedObject::default();
2776                change.object_id = Some(id.to_canonical_string(true));
2777                change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
2778                change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
2779                change.output_version = Some(version.value());
2780                change.output_digest = Some(digest.to_string());
2781                change.id_operation = Some(changed_object::IdOperation::Deleted.into());
2782
2783                changed_objects.push(change);
2784            }
2785
2786            for (id, version, digest) in value.wrapped() {
2787                let mut change = ChangedObject::default();
2788                change.object_id = Some(id.to_canonical_string(true));
2789                change.input_state = Some(changed_object::InputObjectState::Exists.into());
2790                change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
2791                change.output_version = Some(version.value());
2792                change.output_digest = Some(digest.to_string());
2793                change.id_operation = Some(changed_object::IdOperation::Deleted.into());
2794
2795                changed_objects.push(change);
2796            }
2797
2798            for (object_id, version) in value.modified_at_versions() {
2799                let object_id = object_id.to_canonical_string(true);
2800                let version = version.value();
2801                if let Some(changed_object) = changed_objects
2802                    .iter_mut()
2803                    .find(|object| object.object_id() == object_id)
2804                {
2805                    changed_object.input_version = Some(version);
2806                }
2807            }
2808
2809            for (id, version, digest) in value.shared_objects() {
2810                let object_id = id.to_canonical_string(true);
2811                let version = version.value();
2812                let digest = digest.to_string();
2813
2814                if let Some(changed_object) = changed_objects
2815                    .iter_mut()
2816                    .find(|object| object.object_id() == object_id)
2817                {
2818                    changed_object.input_version = Some(version);
2819                    changed_object.input_digest = Some(digest);
2820                } else {
2821                    let mut unchanged_consensus_object = UnchangedConsensusObject::default();
2822                    unchanged_consensus_object.kind = Some(
2823                        unchanged_consensus_object::UnchangedConsensusObjectKind::ReadOnlyRoot
2824                            .into(),
2825                    );
2826                    unchanged_consensus_object.object_id = Some(object_id);
2827                    unchanged_consensus_object.version = Some(version);
2828                    unchanged_consensus_object.digest = Some(digest);
2829
2830                    unchanged_consensus_objects.push(unchanged_consensus_object);
2831                }
2832            }
2833
2834            if mask.contains(Self::GAS_OBJECT_FIELD.name) {
2835                let gas_object_id = value.gas_object().0.0.to_canonical_string(true);
2836                self.gas_object = changed_objects
2837                    .iter()
2838                    .find(|object| object.object_id() == gas_object_id)
2839                    .cloned();
2840            }
2841
2842            if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
2843                self.changed_objects = changed_objects;
2844            }
2845
2846            if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
2847                self.unchanged_consensus_objects = unchanged_consensus_objects;
2848            }
2849        }
2850    }
2851}
2852
2853//
2854// TransactionEffectsV2
2855//
2856
2857impl Merge<&crate::effects::TransactionEffectsV2> for TransactionEffects {
2858    fn merge(
2859        &mut self,
2860        crate::effects::TransactionEffectsV2 {
2861            status,
2862            executed_epoch,
2863            gas_used,
2864            transaction_digest,
2865            gas_object_index,
2866            events_digest,
2867            dependencies,
2868            lamport_version,
2869            changed_objects,
2870            unchanged_consensus_objects,
2871            aux_data_digest,
2872        }: &crate::effects::TransactionEffectsV2,
2873        mask: &FieldMaskTree,
2874    ) {
2875        if mask.contains(Self::VERSION_FIELD.name) {
2876            self.version = Some(2);
2877        }
2878
2879        if mask.contains(Self::STATUS_FIELD.name) {
2880            self.status = Some(status.clone().into());
2881        }
2882
2883        if mask.contains(Self::EPOCH_FIELD.name) {
2884            self.epoch = Some(*executed_epoch);
2885        }
2886
2887        if mask.contains(Self::GAS_USED_FIELD.name) {
2888            self.gas_used = Some(gas_used.clone().into());
2889        }
2890
2891        if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
2892            self.transaction_digest = Some(transaction_digest.to_string());
2893        }
2894
2895        if mask.contains(Self::GAS_OBJECT_FIELD.name) {
2896            self.gas_object = gas_object_index
2897                .map(|index| {
2898                    changed_objects
2899                        .get(index as usize)
2900                        .cloned()
2901                        .map(|(id, change)| {
2902                            let mut message = ChangedObject::from(change);
2903                            message.object_id = Some(id.to_canonical_string(true));
2904                            message
2905                        })
2906                })
2907                .flatten();
2908        }
2909
2910        if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
2911            self.events_digest = events_digest.map(|d| d.to_string());
2912        }
2913
2914        if mask.contains(Self::DEPENDENCIES_FIELD.name) {
2915            self.dependencies = dependencies.iter().map(ToString::to_string).collect();
2916        }
2917
2918        if mask.contains(Self::LAMPORT_VERSION_FIELD.name) {
2919            self.lamport_version = Some(lamport_version.value());
2920        }
2921
2922        if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
2923            self.changed_objects = changed_objects
2924                .clone()
2925                .into_iter()
2926                .map(|(id, change)| {
2927                    let mut message = ChangedObject::from(change);
2928                    message.object_id = Some(id.to_canonical_string(true));
2929                    message
2930                })
2931                .collect();
2932        }
2933
2934        for object in self.changed_objects.iter_mut().chain(&mut self.gas_object) {
2935            if object.output_digest.is_some() && object.output_version.is_none() {
2936                object.output_version = Some(lamport_version.value());
2937            }
2938        }
2939
2940        if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
2941            self.unchanged_consensus_objects = unchanged_consensus_objects
2942                .clone()
2943                .into_iter()
2944                .map(|(id, unchanged)| {
2945                    let mut message = UnchangedConsensusObject::from(unchanged);
2946                    message.object_id = Some(id.to_canonical_string(true));
2947                    message
2948                })
2949                .collect();
2950        }
2951
2952        if mask.contains(Self::AUXILIARY_DATA_DIGEST_FIELD.name) {
2953            self.auxiliary_data_digest = aux_data_digest.map(|d| d.to_string());
2954        }
2955    }
2956}
2957
2958//
2959// ChangedObject
2960//
2961
2962impl From<crate::effects::EffectsObjectChange> for ChangedObject {
2963    fn from(value: crate::effects::EffectsObjectChange) -> Self {
2964        use crate::effects::ObjectIn;
2965        use crate::effects::ObjectOut;
2966        use changed_object::InputObjectState;
2967        use changed_object::OutputObjectState;
2968
2969        let mut message = Self::default();
2970
2971        // Input State
2972        let input_state = match value.input_state {
2973            ObjectIn::NotExist => InputObjectState::DoesNotExist,
2974            ObjectIn::Exist(((version, digest), owner)) => {
2975                message.input_version = Some(version.value());
2976                message.input_digest = Some(digest.to_string());
2977                message.input_owner = Some(owner.into());
2978                InputObjectState::Exists
2979            }
2980        };
2981        message.set_input_state(input_state);
2982
2983        // Output State
2984        let output_state = match value.output_state {
2985            ObjectOut::NotExist => OutputObjectState::DoesNotExist,
2986            ObjectOut::ObjectWrite((digest, owner)) => {
2987                message.output_digest = Some(digest.to_string());
2988                message.output_owner = Some(owner.into());
2989                OutputObjectState::ObjectWrite
2990            }
2991            ObjectOut::PackageWrite((version, digest)) => {
2992                message.output_version = Some(version.value());
2993                message.output_digest = Some(digest.to_string());
2994                OutputObjectState::PackageWrite
2995            }
2996            //TODO
2997            ObjectOut::AccumulatorWriteV1(_) => OutputObjectState::Unknown,
2998        };
2999        message.set_output_state(output_state);
3000
3001        message.set_id_operation(value.id_operation.into());
3002        message
3003    }
3004}
3005
3006//
3007// IdOperation
3008//
3009
3010impl From<crate::effects::IDOperation> for changed_object::IdOperation {
3011    fn from(value: crate::effects::IDOperation) -> Self {
3012        use crate::effects::IDOperation as I;
3013
3014        match value {
3015            I::None => Self::None,
3016            I::Created => Self::Created,
3017            I::Deleted => Self::Deleted,
3018        }
3019    }
3020}
3021
3022//
3023// UnchangedConsensusObject
3024//
3025
3026impl From<crate::effects::UnchangedConsensusKind> for UnchangedConsensusObject {
3027    fn from(value: crate::effects::UnchangedConsensusKind) -> Self {
3028        use crate::effects::UnchangedConsensusKind as K;
3029        use unchanged_consensus_object::UnchangedConsensusObjectKind;
3030
3031        let mut message = Self::default();
3032
3033        let kind = match value {
3034            K::ReadOnlyRoot((version, digest)) => {
3035                message.version = Some(version.value());
3036                message.digest = Some(digest.to_string());
3037                UnchangedConsensusObjectKind::ReadOnlyRoot
3038            }
3039            K::MutateConsensusStreamEnded(version) => {
3040                message.version = Some(version.value());
3041                UnchangedConsensusObjectKind::MutateConsensusStreamEnded
3042            }
3043            K::ReadConsensusStreamEnded(version) => {
3044                message.version = Some(version.value());
3045                UnchangedConsensusObjectKind::ReadConsensusStreamEnded
3046            }
3047            K::Cancelled(version) => {
3048                message.version = Some(version.value());
3049                UnchangedConsensusObjectKind::Canceled
3050            }
3051            K::PerEpochConfig => UnchangedConsensusObjectKind::PerEpochConfig,
3052            // PerEpochConfigWithSequenceNumber { version } => {
3053            //     message.version = Some(version);
3054            //     UnchangedSharedObjectKind::PerEpochConfig
3055            // }
3056        };
3057
3058        message.set_kind(kind);
3059        message
3060    }
3061}
3062
3063//
3064// TransactionChecks
3065//
3066
3067impl From<simulate_transaction_request::TransactionChecks>
3068    for crate::transaction_executor::TransactionChecks
3069{
3070    fn from(value: simulate_transaction_request::TransactionChecks) -> Self {
3071        match value {
3072            simulate_transaction_request::TransactionChecks::Enabled => Self::Enabled,
3073            simulate_transaction_request::TransactionChecks::Disabled => Self::Disabled,
3074            // Default to enabled
3075            _ => Self::Enabled,
3076        }
3077    }
3078}
3079
3080//
3081// Coin-related conversions
3082//
3083
3084impl From<crate::coin_registry::MetadataCapState> for coin_metadata::MetadataCapState {
3085    fn from(value: crate::coin_registry::MetadataCapState) -> Self {
3086        match value {
3087            crate::coin_registry::MetadataCapState::Claimed(_) => {
3088                coin_metadata::MetadataCapState::Claimed
3089            }
3090            crate::coin_registry::MetadataCapState::Unclaimed => {
3091                coin_metadata::MetadataCapState::Unclaimed
3092            }
3093            crate::coin_registry::MetadataCapState::Deleted => {
3094                coin_metadata::MetadataCapState::Deleted
3095            }
3096        }
3097    }
3098}
3099
3100impl From<&crate::coin_registry::Currency> for CoinMetadata {
3101    fn from(value: &crate::coin_registry::Currency) -> Self {
3102        let mut metadata = CoinMetadata::default();
3103        metadata.id = Some(sui_sdk_types::Address::from(value.id.into_bytes()).to_string());
3104        metadata.decimals = Some(value.decimals.into());
3105        metadata.name = Some(value.name.clone());
3106        metadata.symbol = Some(value.symbol.clone());
3107        metadata.description = Some(value.description.clone());
3108        metadata.icon_url = Some(value.icon_url.clone());
3109
3110        match &value.metadata_cap_id {
3111            crate::coin_registry::MetadataCapState::Claimed(id) => {
3112                metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Claimed as i32);
3113                metadata.metadata_cap_id = Some(sui_sdk_types::Address::from(*id).to_string());
3114            }
3115            crate::coin_registry::MetadataCapState::Unclaimed => {
3116                metadata.metadata_cap_state =
3117                    Some(coin_metadata::MetadataCapState::Unclaimed as i32);
3118            }
3119            crate::coin_registry::MetadataCapState::Deleted => {
3120                metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Deleted as i32);
3121            }
3122        }
3123
3124        metadata
3125    }
3126}
3127
3128impl From<crate::coin::CoinMetadata> for CoinMetadata {
3129    fn from(value: crate::coin::CoinMetadata) -> Self {
3130        let mut metadata = CoinMetadata::default();
3131        metadata.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3132        metadata.decimals = Some(value.decimals.into());
3133        metadata.name = Some(value.name);
3134        metadata.symbol = Some(value.symbol);
3135        metadata.description = Some(value.description);
3136        metadata.icon_url = value.icon_url;
3137        metadata
3138    }
3139}
3140
3141impl From<crate::coin_registry::SupplyState> for coin_treasury::SupplyState {
3142    fn from(value: crate::coin_registry::SupplyState) -> Self {
3143        match value {
3144            crate::coin_registry::SupplyState::Fixed(_) => coin_treasury::SupplyState::Fixed,
3145            crate::coin_registry::SupplyState::BurnOnly(_) => coin_treasury::SupplyState::BurnOnly,
3146            crate::coin_registry::SupplyState::Unknown => coin_treasury::SupplyState::Unknown,
3147        }
3148    }
3149}
3150
3151impl From<crate::coin::TreasuryCap> for CoinTreasury {
3152    fn from(value: crate::coin::TreasuryCap) -> Self {
3153        let mut treasury = CoinTreasury::default();
3154        treasury.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3155        treasury.total_supply = Some(value.total_supply.value);
3156        treasury
3157    }
3158}
3159
3160impl From<&crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3161    fn from(value: &crate::coin_registry::RegulatedState) -> Self {
3162        let mut regulated = RegulatedCoinMetadata::default();
3163
3164        match value {
3165            crate::coin_registry::RegulatedState::Regulated {
3166                cap,
3167                allow_global_pause,
3168                variant,
3169            } => {
3170                regulated.deny_cap_object = Some(sui_sdk_types::Address::from(*cap).to_string());
3171                regulated.allow_global_pause = *allow_global_pause;
3172                regulated.variant = Some(*variant as u32);
3173                regulated.coin_regulated_state =
3174                    Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3175            }
3176            crate::coin_registry::RegulatedState::Unregulated => {
3177                regulated.coin_regulated_state =
3178                    Some(regulated_coin_metadata::CoinRegulatedState::Unregulated as i32);
3179            }
3180            crate::coin_registry::RegulatedState::Unknown => {
3181                regulated.coin_regulated_state =
3182                    Some(regulated_coin_metadata::CoinRegulatedState::Unknown as i32);
3183            }
3184        }
3185
3186        regulated
3187    }
3188}
3189
3190impl From<crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3191    fn from(value: crate::coin_registry::RegulatedState) -> Self {
3192        (&value).into()
3193    }
3194}
3195
3196impl From<crate::coin::RegulatedCoinMetadata> for RegulatedCoinMetadata {
3197    fn from(value: crate::coin::RegulatedCoinMetadata) -> Self {
3198        let mut message = RegulatedCoinMetadata::default();
3199        message.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3200        message.coin_metadata_object =
3201            Some(sui_sdk_types::Address::from(value.coin_metadata_object.bytes).to_string());
3202        message.deny_cap_object =
3203            Some(sui_sdk_types::Address::from(value.deny_cap_object.bytes).to_string());
3204        message.coin_regulated_state =
3205            Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3206        message
3207    }
3208}
3209
3210impl TryFrom<&ObjectSet> for crate::full_checkpoint_content::ObjectSet {
3211    type Error = TryFromProtoError;
3212
3213    fn try_from(value: &ObjectSet) -> Result<Self, Self::Error> {
3214        let mut objects = Self::default();
3215
3216        for o in value.objects() {
3217            objects.insert(
3218                o.bcs()
3219                    .deserialize()
3220                    .map_err(|e| TryFromProtoError::invalid("object.bcs", e))?,
3221            );
3222        }
3223
3224        Ok(objects)
3225    }
3226}