1use fastcrypto::traits::ToFromBytes;
14use iota_sdk_types::{
15 address::Address,
16 checkpoint::{
17 CheckpointContents, CheckpointData, CheckpointSummary, CheckpointTransaction,
18 CheckpointTransactionInfo, SignedCheckpointSummary,
19 },
20 crypto::{Bls12381PublicKey, Bls12381Signature, UserSignature},
21 move_core::{Identifier, StructTag, TypeParseError, TypeTag},
22 object::Object,
23 transaction::SignedTransaction,
24 validator::{ValidatorAggregatedSignature, ValidatorCommittee, ValidatorCommitteeMember},
25};
26use tap::Pipe;
27
28#[derive(Debug)]
29pub struct SdkTypeConversionError(pub String);
30
31impl std::fmt::Display for SdkTypeConversionError {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 f.write_str(&self.0)
34 }
35}
36
37impl std::error::Error for SdkTypeConversionError {}
38
39impl From<TypeParseError> for SdkTypeConversionError {
40 fn from(value: TypeParseError) -> Self {
41 Self(value.to_string())
42 }
43}
44
45impl From<anyhow::Error> for SdkTypeConversionError {
46 fn from(value: anyhow::Error) -> Self {
47 Self(value.to_string())
48 }
49}
50
51impl From<bcs::Error> for SdkTypeConversionError {
52 fn from(value: bcs::Error) -> Self {
53 Self(value.to_string())
54 }
55}
56
57impl TryFrom<crate::object::Object> for Object {
58 type Error = SdkTypeConversionError;
59
60 fn try_from(value: crate::object::Object) -> Result<Self, Self::Error> {
61 Self {
62 data: value.data.clone(),
63 owner: value.owner,
64 previous_transaction: value.previous_transaction,
65 storage_rebate: value.storage_rebate,
66 }
67 .pipe(Ok)
68 }
69}
70
71impl TryFrom<crate::messages_checkpoint::CheckpointContents> for CheckpointContents {
72 type Error = SdkTypeConversionError;
73
74 fn try_from(
75 value: crate::messages_checkpoint::CheckpointContents,
76 ) -> Result<Self, Self::Error> {
77 Self(
78 value
79 .into_iter_with_signatures()
80 .map(|(digests, signatures)| {
81 let signatures_result = signatures
82 .into_iter()
83 .map(TryInto::try_into)
84 .collect::<Result<Vec<UserSignature>, _>>();
85
86 match signatures_result {
87 Ok(signatures) => Ok(CheckpointTransactionInfo {
88 transaction: digests.transaction,
89 effects: digests.effects,
90 signatures,
91 }),
92 Err(e) => Err(SdkTypeConversionError::from(e)),
93 }
94 })
95 .collect::<Result<Vec<_>, _>>()?,
96 )
97 .pipe(Ok)
98 }
99}
100
101impl TryFrom<CheckpointContents> for crate::messages_checkpoint::CheckpointContents {
102 type Error = SdkTypeConversionError;
103
104 fn try_from(value: CheckpointContents) -> Result<Self, Self::Error> {
105 let (transactions, user_signatures) = value.0.into_iter().fold(
106 (Vec::new(), Vec::new()),
107 |(mut transactions, mut user_signatures), info| {
108 transactions.push(crate::base_types::ExecutionDigests {
109 transaction: info.transaction,
110 effects: info.effects,
111 });
112 user_signatures.push(
113 info.signatures
114 .into_iter()
115 .map(TryInto::try_into)
116 .collect::<Result<_, _>>(),
117 );
118 (transactions, user_signatures)
119 },
120 );
121 crate::messages_checkpoint::CheckpointContents::new_with_digests_and_signatures(
122 transactions,
123 user_signatures.into_iter().collect::<Result<Vec<_>, _>>()?,
124 )
125 .pipe(Ok)
126 }
127}
128
129impl TryFrom<crate::full_checkpoint_content::CheckpointData> for CheckpointData {
130 type Error = SdkTypeConversionError;
131
132 fn try_from(
133 value: crate::full_checkpoint_content::CheckpointData,
134 ) -> Result<Self, Self::Error> {
135 Self {
136 checkpoint_summary: value.checkpoint_summary.try_into()?,
137 checkpoint_contents: value.checkpoint_contents.try_into()?,
138 transactions: value
139 .transactions
140 .into_iter()
141 .map(TryInto::try_into)
142 .collect::<Result<_, _>>()?,
143 }
144 .pipe(Ok)
145 }
146}
147
148impl TryFrom<CheckpointData> for crate::full_checkpoint_content::CheckpointData {
149 type Error = SdkTypeConversionError;
150
151 fn try_from(value: CheckpointData) -> Result<Self, Self::Error> {
152 Self {
153 checkpoint_summary: value.checkpoint_summary.try_into()?,
154 checkpoint_contents: value.checkpoint_contents.try_into()?,
155 transactions: value
156 .transactions
157 .into_iter()
158 .map(TryInto::try_into)
159 .collect::<Result<_, _>>()?,
160 }
161 .pipe(Ok)
162 }
163}
164
165impl TryFrom<crate::full_checkpoint_content::CheckpointTransaction> for CheckpointTransaction {
166 type Error = SdkTypeConversionError;
167
168 fn try_from(
169 value: crate::full_checkpoint_content::CheckpointTransaction,
170 ) -> Result<Self, Self::Error> {
171 let input_objects = value
172 .input_objects
173 .into_iter()
174 .map(TryInto::try_into)
175 .collect::<Result<_, _>>();
176 let output_objects = value
177 .output_objects
178 .into_iter()
179 .map(TryInto::try_into)
180 .collect::<Result<_, _>>();
181 match (input_objects, output_objects) {
182 (Ok(input_objects), Ok(output_objects)) => Ok(Self {
183 transaction: value.transaction.try_into()?,
184 effects: value.effects,
185 events: value.events,
186 input_objects,
187 output_objects,
188 }),
189 (Err(e), _) | (_, Err(e)) => Err(e),
190 }
191 }
192}
193
194impl TryFrom<CheckpointTransaction> for crate::full_checkpoint_content::CheckpointTransaction {
195 type Error = SdkTypeConversionError;
196
197 fn try_from(value: CheckpointTransaction) -> Result<Self, Self::Error> {
198 let input_objects = value
199 .input_objects
200 .into_iter()
201 .map(crate::object::Object::from)
202 .collect();
203 let output_objects = value
204 .output_objects
205 .into_iter()
206 .map(crate::object::Object::from)
207 .collect();
208
209 Ok(Self {
210 transaction: value.transaction.try_into()?,
211 effects: value.effects,
212 events: value.events,
213 input_objects,
214 output_objects,
215 })
216 }
217}
218
219impl TryFrom<crate::signature::GenericSignature> for UserSignature {
220 type Error = bcs::Error;
221
222 fn try_from(value: crate::signature::GenericSignature) -> Result<Self, Self::Error> {
223 bcs::from_bytes(&bcs::to_bytes(&value)?)
224 }
225}
226
227impl TryFrom<UserSignature> for crate::signature::GenericSignature {
228 type Error = bcs::Error;
229
230 fn try_from(value: UserSignature) -> Result<Self, Self::Error> {
231 bcs::from_bytes(&bcs::to_bytes(&value)?)
232 }
233}
234
235impl TryFrom<crate::messages_checkpoint::CheckpointSummary> for CheckpointSummary {
236 type Error = SdkTypeConversionError;
237
238 fn try_from(value: crate::messages_checkpoint::CheckpointSummary) -> Result<Self, Self::Error> {
239 Self {
240 epoch: value.epoch,
241 sequence_number: value.sequence_number,
242 network_total_transactions: value.network_total_transactions,
243 content_digest: value.content_digest,
244 previous_digest: value.previous_digest,
245 epoch_rolling_gas_cost_summary: value.epoch_rolling_gas_cost_summary,
246 timestamp_ms: value.timestamp_ms,
247 checkpoint_commitments: value.checkpoint_commitments,
248 end_of_epoch_data: value.end_of_epoch_data,
249 version_specific_data: value.version_specific_data,
250 }
251 .pipe(Ok)
252 }
253}
254
255impl TryFrom<CheckpointSummary> for crate::messages_checkpoint::CheckpointSummary {
256 type Error = SdkTypeConversionError;
257
258 fn try_from(value: CheckpointSummary) -> Result<Self, Self::Error> {
259 Self {
260 epoch: value.epoch,
261 sequence_number: value.sequence_number,
262 network_total_transactions: value.network_total_transactions,
263 content_digest: value.content_digest,
264 previous_digest: value.previous_digest,
265 epoch_rolling_gas_cost_summary: value.epoch_rolling_gas_cost_summary,
266 timestamp_ms: value.timestamp_ms,
267 checkpoint_commitments: value.checkpoint_commitments,
268 end_of_epoch_data: value.end_of_epoch_data,
269 version_specific_data: value.version_specific_data,
270 }
271 .pipe(Ok)
272 }
273}
274
275impl TryFrom<crate::messages_checkpoint::CertifiedCheckpointSummary> for SignedCheckpointSummary {
276 type Error = SdkTypeConversionError;
277
278 fn try_from(
279 value: crate::messages_checkpoint::CertifiedCheckpointSummary,
280 ) -> Result<Self, Self::Error> {
281 let (data, sig) = value.into_data_and_sig();
282 Self {
283 checkpoint: data.try_into()?,
284 signature: sig.into(),
285 }
286 .pipe(Ok)
287 }
288}
289
290impl TryFrom<SignedCheckpointSummary> for crate::messages_checkpoint::CertifiedCheckpointSummary {
291 type Error = SdkTypeConversionError;
292
293 fn try_from(value: SignedCheckpointSummary) -> Result<Self, Self::Error> {
294 Self::new_from_data_and_sig(
295 crate::messages_checkpoint::CheckpointSummary::try_from(value.checkpoint)?,
296 crate::crypto::AuthorityQuorumSignInfo::<true>::from(value.signature),
297 )
298 .pipe(Ok)
299 }
300}
301
302impl<const T: bool> From<crate::crypto::AuthorityQuorumSignInfo<T>>
303 for ValidatorAggregatedSignature
304{
305 fn from(value: crate::crypto::AuthorityQuorumSignInfo<T>) -> Self {
306 let crate::crypto::AuthorityQuorumSignInfo {
307 epoch,
308 signature,
309 signers_map,
310 } = value;
311
312 Self {
313 epoch,
314 signature: Bls12381Signature::from_bytes(signature.as_ref()).unwrap(),
315 bitmap: signers_map,
316 }
317 }
318}
319
320impl<const T: bool> From<ValidatorAggregatedSignature>
321 for crate::crypto::AuthorityQuorumSignInfo<T>
322{
323 fn from(value: ValidatorAggregatedSignature) -> Self {
324 let ValidatorAggregatedSignature {
325 epoch,
326 signature,
327 bitmap,
328 } = value;
329
330 Self {
331 epoch,
332 signature: crate::crypto::AggregateAuthoritySignature::from_bytes(signature.as_bytes())
333 .unwrap(),
334 signers_map: bitmap,
335 }
336 }
337}
338
339impl TryFrom<crate::transaction::SenderSignedData> for SignedTransaction {
340 type Error = SdkTypeConversionError;
341
342 fn try_from(value: crate::transaction::SenderSignedData) -> Result<Self, Self::Error> {
343 let crate::transaction::SenderSignedTransaction {
344 intent_message,
345 tx_signatures,
346 } = value.into_inner();
347
348 Self {
349 transaction: intent_message.value,
350 signatures: tx_signatures
351 .into_iter()
352 .map(TryInto::try_into)
353 .collect::<Result<_, _>>()?,
354 }
355 .pipe(Ok)
356 }
357}
358
359impl TryFrom<SignedTransaction> for crate::transaction::SenderSignedData {
360 type Error = SdkTypeConversionError;
361
362 fn try_from(value: SignedTransaction) -> Result<Self, Self::Error> {
363 let SignedTransaction {
364 transaction,
365 signatures,
366 } = value;
367
368 Self::new(
369 transaction,
370 signatures
371 .into_iter()
372 .map(TryInto::try_into)
373 .collect::<Result<_, _>>()?,
374 )
375 .pipe(Ok)
376 }
377}
378
379impl TryFrom<crate::transaction::Transaction> for SignedTransaction {
380 type Error = SdkTypeConversionError;
381
382 fn try_from(value: crate::transaction::Transaction) -> Result<Self, Self::Error> {
383 value.into_data().try_into()
384 }
385}
386
387impl TryFrom<SignedTransaction> for crate::transaction::Transaction {
388 type Error = SdkTypeConversionError;
389
390 fn try_from(value: SignedTransaction) -> Result<Self, Self::Error> {
391 Ok(Self::new(value.try_into()?))
392 }
393}
394
395pub fn type_tag_core_to_sdk(value: &move_core_types::language_storage::TypeTag) -> TypeTag {
396 match value {
397 move_core_types::language_storage::TypeTag::Bool => TypeTag::Bool,
398 move_core_types::language_storage::TypeTag::U8 => TypeTag::U8,
399 move_core_types::language_storage::TypeTag::U64 => TypeTag::U64,
400 move_core_types::language_storage::TypeTag::U128 => TypeTag::U128,
401 move_core_types::language_storage::TypeTag::Address => TypeTag::Address,
402 move_core_types::language_storage::TypeTag::Signer => TypeTag::Signer,
403 move_core_types::language_storage::TypeTag::Vector(type_tag) => {
404 TypeTag::Vector(Box::new(type_tag_core_to_sdk(type_tag)))
405 }
406 move_core_types::language_storage::TypeTag::Struct(struct_tag) => {
407 TypeTag::Struct(Box::new(struct_tag_core_to_sdk(struct_tag)))
408 }
409 move_core_types::language_storage::TypeTag::U16 => TypeTag::U16,
410 move_core_types::language_storage::TypeTag::U32 => TypeTag::U32,
411 move_core_types::language_storage::TypeTag::U256 => TypeTag::U256,
412 }
413}
414
415pub fn type_tag_sdk_to_core(value: &TypeTag) -> move_core_types::language_storage::TypeTag {
416 match value {
417 TypeTag::Bool => move_core_types::language_storage::TypeTag::Bool,
418 TypeTag::U8 => move_core_types::language_storage::TypeTag::U8,
419 TypeTag::U64 => move_core_types::language_storage::TypeTag::U64,
420 TypeTag::U128 => move_core_types::language_storage::TypeTag::U128,
421 TypeTag::Address => move_core_types::language_storage::TypeTag::Address,
422 TypeTag::Signer => move_core_types::language_storage::TypeTag::Signer,
423 TypeTag::Vector(type_tag) => move_core_types::language_storage::TypeTag::Vector(Box::new(
424 type_tag_sdk_to_core(type_tag),
425 )),
426 TypeTag::Struct(struct_tag) => move_core_types::language_storage::TypeTag::Struct(
427 Box::new(struct_tag_sdk_to_core(struct_tag)),
428 ),
429 TypeTag::U16 => move_core_types::language_storage::TypeTag::U16,
430 TypeTag::U32 => move_core_types::language_storage::TypeTag::U32,
431 TypeTag::U256 => move_core_types::language_storage::TypeTag::U256,
432 }
433}
434
435pub fn identifier_core_to_sdk(value: &move_core_types::identifier::IdentStr) -> Identifier {
436 Identifier::new_unchecked(value.as_str())
437}
438
439pub fn identifier_sdk_to_core(value: &Identifier) -> move_core_types::identifier::Identifier {
440 unsafe { move_core_types::identifier::Identifier::new_unchecked(value.as_str()) }
443}
444
445pub fn struct_tag_core_to_sdk(value: &move_core_types::language_storage::StructTag) -> StructTag {
446 let move_core_types::language_storage::StructTag {
447 address,
448 module,
449 name,
450 type_params,
451 } = value;
452
453 let address = Address::new(address.into_bytes());
454 let module = identifier_core_to_sdk(module);
455 let name = identifier_core_to_sdk(name);
456 let type_params = type_params.iter().map(type_tag_core_to_sdk).collect();
457 StructTag::new(address, module, name, type_params)
458}
459
460pub fn struct_tag_sdk_to_core(value: &StructTag) -> move_core_types::language_storage::StructTag {
461 let address =
462 move_core_types::account_address::AccountAddress::new(value.address().into_bytes());
463 let module = identifier_sdk_to_core(value.module());
464 let name = identifier_sdk_to_core(value.name());
465 let type_params = value
466 .type_params()
467 .iter()
468 .map(type_tag_sdk_to_core)
469 .collect();
470 move_core_types::language_storage::StructTag {
471 address,
472 module,
473 name,
474 type_params,
475 }
476}
477
478impl From<crate::committee::Committee> for ValidatorCommittee {
479 fn from(value: crate::committee::Committee) -> Self {
480 Self {
481 epoch: value.epoch(),
482 members: value
483 .voting_rights
484 .into_iter()
485 .map(|(name, stake)| ValidatorCommitteeMember {
486 public_key: name.into(),
487 stake,
488 })
489 .collect(),
490 }
491 }
492}
493
494impl From<ValidatorCommittee> for crate::committee::Committee {
495 fn from(value: ValidatorCommittee) -> Self {
496 let ValidatorCommittee { epoch, members } = value;
497
498 Self::new(
499 epoch,
500 members
501 .into_iter()
502 .map(|member| (member.public_key.into(), member.stake))
503 .collect(),
504 )
505 }
506}
507
508impl From<crate::crypto::AuthorityPublicKeyBytes> for Bls12381PublicKey {
509 fn from(value: crate::crypto::AuthorityPublicKeyBytes) -> Self {
510 Self::new(value.0)
511 }
512}
513
514impl From<Bls12381PublicKey> for crate::crypto::AuthorityPublicKeyBytes {
515 fn from(value: Bls12381PublicKey) -> Self {
516 Self::new(value.into_inner())
517 }
518}