1use std::sync::Arc;
2
3use starknet_rust_core::types::{self as core, contract::legacy as contract_legacy, Felt};
4
5use super::{
6 state_update::{DeclaredContract, DeployedContract, StateDiff, StorageDiff},
7 transaction::{DataAvailabilityMode, ResourceBounds, ResourceBoundsMapping},
8 *,
9};
10
11#[derive(Debug, thiserror::Error)]
12#[error("unable to convert type")]
13pub struct ConversionError;
14
15pub(crate) struct ConfirmedReceiptWithContext {
16 pub receipt: ConfirmedTransactionReceipt,
17 pub transaction: TransactionType,
18 pub finality: BlockStatus,
19}
20
21impl TryFrom<core::BlockId> for BlockId {
22 type Error = ConversionError;
23
24 fn try_from(value: core::BlockId) -> Result<Self, Self::Error> {
25 match value {
26 core::BlockId::Hash(hash) => Ok(Self::Hash(hash)),
27 core::BlockId::Number(num) => Ok(Self::Number(num)),
28 core::BlockId::Tag(core::BlockTag::Latest) => Ok(Self::Latest),
29 core::BlockId::Tag(core::BlockTag::PreConfirmed) => Ok(Self::Pending),
30 core::BlockId::Tag(core::BlockTag::L1Accepted) => Err(ConversionError),
31 }
32 }
33}
34
35impl TryFrom<Block> for core::MaybePreConfirmedBlockWithTxHashes {
36 type Error = ConversionError;
37
38 fn try_from(value: Block) -> Result<Self, Self::Error> {
39 match (value.block_hash, value.block_number, value.state_root) {
40 (Some(block_hash), Some(block_number), Some(state_root)) => {
42 Ok(Self::Block(core::BlockWithTxHashes {
43 status: value.status.try_into()?,
44 block_hash,
45 parent_hash: value.parent_block_hash,
46 block_number,
47 new_root: state_root,
48 timestamp: value.timestamp,
49 sequencer_address: value.sequencer_address.unwrap_or_default(),
50 l1_gas_price: value.l1_gas_price,
51 l2_gas_price: value.l2_gas_price,
52 l1_data_gas_price: value.l1_data_gas_price,
53 l1_da_mode: value.l1_da_mode,
54 starknet_version: value.starknet_version.ok_or(ConversionError)?,
55 transactions: value
56 .transactions
57 .iter()
58 .map(|tx| tx.transaction_hash())
59 .collect(),
60 }))
61 }
62 (None, None, None) => {
64 Err(ConversionError)
70 }
71 _ => Err(ConversionError),
73 }
74 }
75}
76
77impl TryFrom<Block> for core::MaybePreConfirmedBlockWithTxs {
78 type Error = ConversionError;
79
80 fn try_from(value: Block) -> Result<Self, Self::Error> {
81 match (value.block_hash, value.block_number, value.state_root) {
82 (Some(block_hash), Some(block_number), Some(state_root)) => {
84 Ok(Self::Block(core::BlockWithTxs {
85 status: value.status.try_into()?,
86 block_hash,
87 parent_hash: value.parent_block_hash,
88 block_number,
89 new_root: state_root,
90 timestamp: value.timestamp,
91 sequencer_address: value.sequencer_address.unwrap_or_default(),
92 l1_gas_price: value.l1_gas_price,
93 l2_gas_price: value.l2_gas_price,
94 l1_data_gas_price: value.l1_data_gas_price,
95 l1_da_mode: value.l1_da_mode,
96 starknet_version: value.starknet_version.ok_or(ConversionError)?,
97 transactions: value
98 .transactions
99 .into_iter()
100 .map(|tx| tx.try_into())
101 .collect::<Result<_, _>>()?,
102 }))
103 }
104 (None, None, None) => {
106 Err(ConversionError)
112 }
113 _ => Err(ConversionError),
115 }
116 }
117}
118
119impl TryFrom<Block> for core::MaybePreConfirmedBlockWithReceipts {
120 type Error = ConversionError;
121
122 fn try_from(value: Block) -> Result<Self, Self::Error> {
123 if value.transactions.len() != value.transaction_receipts.len() {
124 return Err(ConversionError);
125 }
126
127 let mut transactions = vec![];
128
129 for (tx, receipt) in value
130 .transactions
131 .into_iter()
132 .zip(value.transaction_receipts.into_iter())
133 {
134 let core_tx = tx.clone().try_into()?;
135
136 let tx_with_receipt = ConfirmedReceiptWithContext {
137 receipt,
138 transaction: tx,
139 finality: value.status,
140 };
141
142 transactions.push(core::TransactionWithReceipt {
143 transaction: core_tx,
144 receipt: tx_with_receipt.try_into()?,
145 });
146 }
147
148 match (value.block_hash, value.block_number, value.state_root) {
149 (Some(block_hash), Some(block_number), Some(state_root)) => {
151 Ok(Self::Block(core::BlockWithReceipts {
152 status: value.status.try_into()?,
153 block_hash,
154 parent_hash: value.parent_block_hash,
155 block_number,
156 new_root: state_root,
157 timestamp: value.timestamp,
158 sequencer_address: value.sequencer_address.unwrap_or_default(),
159 l1_gas_price: value.l1_gas_price,
160 l2_gas_price: value.l2_gas_price,
161 l1_data_gas_price: value.l1_data_gas_price,
162 l1_da_mode: value.l1_da_mode,
163 starknet_version: value.starknet_version.ok_or(ConversionError)?,
164 transactions,
165 }))
166 }
167 (None, None, None) => {
169 Err(ConversionError)
175 }
176 _ => Err(ConversionError),
178 }
179 }
180}
181
182impl TryFrom<BlockStatus> for core::BlockStatus {
183 type Error = ConversionError;
184
185 fn try_from(value: BlockStatus) -> Result<Self, Self::Error> {
186 match value {
187 BlockStatus::Pending => Ok(Self::PreConfirmed),
188 BlockStatus::Aborted | BlockStatus::Reverted => Err(ConversionError),
189 BlockStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
190 BlockStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
191 }
192 }
193}
194
195impl TryFrom<TransactionType> for core::Transaction {
196 type Error = ConversionError;
197
198 fn try_from(value: TransactionType) -> Result<Self, Self::Error> {
199 match value {
200 TransactionType::Declare(inner) => Ok(Self::Declare(inner.try_into()?)),
201 TransactionType::Deploy(inner) => Ok(Self::Deploy(inner.try_into()?)),
202 TransactionType::DeployAccount(inner) => Ok(Self::DeployAccount(inner.try_into()?)),
203 TransactionType::InvokeFunction(inner) => Ok(Self::Invoke(inner.try_into()?)),
204 TransactionType::L1Handler(inner) => Ok(Self::L1Handler(inner.try_into()?)),
205 }
206 }
207}
208
209impl TryFrom<TransactionType> for core::TransactionContent {
210 type Error = ConversionError;
211
212 fn try_from(value: TransactionType) -> Result<Self, Self::Error> {
213 let tx: core::Transaction = value.try_into()?;
214 Ok(tx.into())
215 }
216}
217
218impl TryFrom<DeclareTransaction> for core::DeclareTransaction {
219 type Error = ConversionError;
220
221 fn try_from(value: DeclareTransaction) -> Result<Self, Self::Error> {
222 if value.version == Felt::ZERO {
223 Ok(Self::V0(core::DeclareTransactionV0 {
224 transaction_hash: value.transaction_hash,
225 max_fee: value.max_fee.ok_or(ConversionError)?,
226 signature: value.signature,
227 class_hash: value.class_hash,
228 sender_address: value.sender_address,
229 }))
230 } else if value.version == Felt::ONE {
231 Ok(Self::V1(core::DeclareTransactionV1 {
232 transaction_hash: value.transaction_hash,
233 max_fee: value.max_fee.ok_or(ConversionError)?,
234 signature: value.signature,
235 nonce: value.nonce,
236 class_hash: value.class_hash,
237 sender_address: value.sender_address,
238 }))
239 } else if value.version == Felt::TWO {
240 Ok(Self::V2(core::DeclareTransactionV2 {
241 transaction_hash: value.transaction_hash,
242 max_fee: value.max_fee.ok_or(ConversionError)?,
243 signature: value.signature,
244 nonce: value.nonce,
245 class_hash: value.class_hash,
246 compiled_class_hash: value.compiled_class_hash.ok_or(ConversionError)?,
247 sender_address: value.sender_address,
248 }))
249 } else if value.version == Felt::THREE {
250 Ok(Self::V3(core::DeclareTransactionV3 {
251 transaction_hash: value.transaction_hash,
252 sender_address: value.sender_address,
253 compiled_class_hash: value.compiled_class_hash.ok_or(ConversionError)?,
254 signature: value.signature,
255 nonce: value.nonce,
256 class_hash: value.class_hash,
257 resource_bounds: value.resource_bounds.ok_or(ConversionError)?.into(),
258 tip: value.tip.ok_or(ConversionError)?,
259 paymaster_data: value.paymaster_data.ok_or(ConversionError)?,
260 account_deployment_data: value.account_deployment_data.ok_or(ConversionError)?,
261 nonce_data_availability_mode: value
262 .nonce_data_availability_mode
263 .ok_or(ConversionError)?
264 .into(),
265 fee_data_availability_mode: value
266 .fee_data_availability_mode
267 .ok_or(ConversionError)?
268 .into(),
269 }))
270 } else {
271 Err(ConversionError)
272 }
273 }
274}
275
276impl TryFrom<DeployTransaction> for core::DeployTransaction {
277 type Error = ConversionError;
278
279 fn try_from(value: DeployTransaction) -> Result<Self, Self::Error> {
280 Ok(Self {
281 transaction_hash: value.transaction_hash,
282 class_hash: value.class_hash,
283 version: value.version,
284 contract_address_salt: value.contract_address_salt,
285 constructor_calldata: value.constructor_calldata,
286 })
287 }
288}
289
290impl TryFrom<DeployAccountTransaction> for core::DeployAccountTransaction {
291 type Error = ConversionError;
292
293 fn try_from(value: DeployAccountTransaction) -> Result<Self, Self::Error> {
294 if value.version == Felt::ONE {
295 Ok(Self::V1(core::DeployAccountTransactionV1 {
296 transaction_hash: value.transaction_hash,
297 max_fee: value.max_fee.ok_or(ConversionError)?,
298 signature: value.signature,
299 nonce: value.nonce,
300 contract_address_salt: value.contract_address_salt,
301 constructor_calldata: value.constructor_calldata,
302 class_hash: value.class_hash,
303 }))
304 } else if value.version == Felt::THREE {
305 Ok(Self::V3(core::DeployAccountTransactionV3 {
306 transaction_hash: value.transaction_hash,
307 signature: value.signature,
308 nonce: value.nonce,
309 contract_address_salt: value.contract_address_salt,
310 constructor_calldata: value.constructor_calldata,
311 class_hash: value.class_hash,
312 resource_bounds: value.resource_bounds.ok_or(ConversionError)?.into(),
313 tip: value.tip.ok_or(ConversionError)?,
314 paymaster_data: value.paymaster_data.ok_or(ConversionError)?,
315 nonce_data_availability_mode: value
316 .nonce_data_availability_mode
317 .ok_or(ConversionError)?
318 .into(),
319 fee_data_availability_mode: value
320 .fee_data_availability_mode
321 .ok_or(ConversionError)?
322 .into(),
323 }))
324 } else {
325 Err(ConversionError)
326 }
327 }
328}
329
330impl TryFrom<InvokeFunctionTransaction> for core::InvokeTransaction {
331 type Error = ConversionError;
332
333 fn try_from(value: InvokeFunctionTransaction) -> Result<Self, Self::Error> {
334 if value.version == Felt::ZERO {
335 Ok(Self::V0(core::InvokeTransactionV0 {
336 transaction_hash: value.transaction_hash,
337 max_fee: value.max_fee.ok_or(ConversionError)?,
338 signature: value.signature,
339 contract_address: value.sender_address,
340 entry_point_selector: value.entry_point_selector.ok_or(ConversionError)?,
341 calldata: value.calldata,
342 }))
343 } else if value.version == Felt::ONE {
344 Ok(Self::V1(core::InvokeTransactionV1 {
345 transaction_hash: value.transaction_hash,
346 max_fee: value.max_fee.ok_or(ConversionError)?,
347 signature: value.signature,
348 nonce: value.nonce.ok_or(ConversionError)?,
349 sender_address: value.sender_address,
350 calldata: value.calldata,
351 }))
352 } else if value.version == Felt::THREE {
353 Ok(Self::V3(core::InvokeTransactionV3 {
354 transaction_hash: value.transaction_hash,
355 sender_address: value.sender_address,
356 calldata: value.calldata,
357 signature: value.signature,
358 nonce: value.nonce.ok_or(ConversionError)?,
359 resource_bounds: value.resource_bounds.ok_or(ConversionError)?.into(),
360 tip: value.tip.ok_or(ConversionError)?,
361 paymaster_data: value.paymaster_data.ok_or(ConversionError)?,
362 account_deployment_data: value.account_deployment_data.ok_or(ConversionError)?,
363 nonce_data_availability_mode: value
364 .nonce_data_availability_mode
365 .ok_or(ConversionError)?
366 .into(),
367 fee_data_availability_mode: value
368 .fee_data_availability_mode
369 .ok_or(ConversionError)?
370 .into(),
371 }))
372 } else {
373 Err(ConversionError)
374 }
375 }
376}
377
378impl TryFrom<L1HandlerTransaction> for core::L1HandlerTransaction {
379 type Error = ConversionError;
380
381 fn try_from(value: L1HandlerTransaction) -> Result<Self, Self::Error> {
382 Ok(Self {
383 transaction_hash: value.transaction_hash,
384 version: value.version,
385 nonce: {
386 let nonce_bytes = value.nonce.unwrap_or_default().to_bytes_le();
388 if nonce_bytes.iter().skip(8).any(|&x| x != 0) {
389 return Err(ConversionError);
390 }
391 u64::from_le_bytes(nonce_bytes[..8].try_into().unwrap())
392 },
393 contract_address: value.contract_address,
394 entry_point_selector: value.entry_point_selector,
395 calldata: value.calldata,
396 })
397 }
398}
399
400impl From<ResourceBoundsMapping> for core::ResourceBoundsMapping {
401 fn from(value: ResourceBoundsMapping) -> Self {
402 Self {
403 l1_gas: value.l1_gas.into(),
404 l1_data_gas: value.l1_data_gas.into(),
405 l2_gas: value.l2_gas.into(),
406 }
407 }
408}
409
410impl From<core::ResourceBoundsMapping> for ResourceBoundsMapping {
411 fn from(value: core::ResourceBoundsMapping) -> Self {
412 Self {
413 l1_gas: value.l1_gas.into(),
414 l1_data_gas: value.l1_data_gas.into(),
415 l2_gas: value.l2_gas.into(),
416 }
417 }
418}
419
420impl From<ResourceBounds> for core::ResourceBounds {
421 fn from(value: ResourceBounds) -> Self {
422 Self {
423 max_amount: value.max_amount,
424 max_price_per_unit: value.max_price_per_unit,
425 }
426 }
427}
428
429impl From<core::ResourceBounds> for ResourceBounds {
430 fn from(value: core::ResourceBounds) -> Self {
431 Self {
432 max_amount: value.max_amount,
433 max_price_per_unit: value.max_price_per_unit,
434 }
435 }
436}
437
438impl From<DataAvailabilityMode> for core::DataAvailabilityMode {
439 fn from(value: DataAvailabilityMode) -> Self {
440 match value {
441 DataAvailabilityMode::L1 => Self::L1,
442 DataAvailabilityMode::L2 => Self::L2,
443 }
444 }
445}
446
447impl From<core::DataAvailabilityMode> for DataAvailabilityMode {
448 fn from(value: core::DataAvailabilityMode) -> Self {
449 match value {
450 core::DataAvailabilityMode::L1 => Self::L1,
451 core::DataAvailabilityMode::L2 => Self::L2,
452 }
453 }
454}
455
456impl TryFrom<StateUpdate> for core::MaybePreConfirmedStateUpdate {
457 type Error = ConversionError;
458
459 fn try_from(value: StateUpdate) -> Result<Self, Self::Error> {
460 match (value.block_hash, value.new_root, value.old_root) {
461 (Some(block_hash), Some(new_root), Some(old_root)) => {
462 Ok(Self::Update(core::StateUpdate {
463 block_hash,
464 new_root,
465 old_root,
466 state_diff: value.state_diff.into(),
467 }))
468 }
469 (None, None, old_root) => Ok(Self::PreConfirmedUpdate(core::PreConfirmedStateUpdate {
470 old_root,
471 state_diff: value.state_diff.into(),
472 })),
473 _ => Err(ConversionError),
474 }
475 }
476}
477
478impl From<StateDiff> for core::StateDiff {
479 fn from(value: StateDiff) -> Self {
480 Self {
481 storage_diffs: value
482 .storage_diffs
483 .into_iter()
484 .map(|(key, value)| core::ContractStorageDiffItem {
485 address: key,
486 storage_entries: value.into_iter().map(|item| item.into()).collect(),
487 })
488 .collect(),
489 deprecated_declared_classes: value.old_declared_contracts,
490 declared_classes: value
491 .declared_classes
492 .into_iter()
493 .map(|item| item.into())
494 .collect(),
495 migrated_compiled_classes: value
496 .migrated_compiled_classes
497 .map(|classes| classes.into_iter().map(|item| item.into()).collect()),
498 deployed_contracts: value
499 .deployed_contracts
500 .into_iter()
501 .map(|item| item.into())
502 .collect(),
503 replaced_classes: value
504 .replaced_classes
505 .into_iter()
506 .map(|item| item.into())
507 .collect(),
508 nonces: value
509 .nonces
510 .into_iter()
511 .map(|(key, value)| core::NonceUpdate {
512 contract_address: key,
513 nonce: value,
514 })
515 .collect(),
516 }
517 }
518}
519
520impl From<StorageDiff> for core::StorageEntry {
521 fn from(value: StorageDiff) -> Self {
522 Self {
523 key: value.key,
524 value: value.value,
525 }
526 }
527}
528
529impl From<DeclaredContract> for core::DeclaredClassItem {
530 fn from(value: DeclaredContract) -> Self {
531 Self {
532 class_hash: value.class_hash,
533 compiled_class_hash: value.compiled_class_hash,
534 }
535 }
536}
537
538impl From<DeclaredContract> for core::MigratedCompiledClassItem {
539 fn from(value: DeclaredContract) -> Self {
540 Self {
541 class_hash: value.class_hash,
542 compiled_class_hash: value.compiled_class_hash,
543 }
544 }
545}
546
547impl From<DeployedContract> for core::DeployedContractItem {
548 fn from(value: DeployedContract) -> Self {
549 Self {
550 address: value.address,
551 class_hash: value.class_hash,
552 }
553 }
554}
555
556impl From<DeployedContract> for core::ReplacedClassItem {
557 fn from(value: DeployedContract) -> Self {
558 Self {
559 contract_address: value.address,
560 class_hash: value.class_hash,
561 }
562 }
563}
564
565impl TryFrom<TransactionInfo> for core::Transaction {
566 type Error = ConversionError;
567
568 fn try_from(value: TransactionInfo) -> Result<Self, Self::Error> {
569 match value.r#type {
570 Some(tx) => tx.try_into(),
571 None => Err(ConversionError),
572 }
573 }
574}
575
576impl From<L2ToL1Message> for core::MsgToL1 {
577 fn from(value: L2ToL1Message) -> Self {
578 Self {
579 from_address: value.from_address,
580 to_address: Felt::from_bytes_be_slice(&value.to_address.0),
582 payload: value.payload,
583 }
584 }
585}
586
587impl From<Event> for core::Event {
588 fn from(value: Event) -> Self {
589 Self {
590 from_address: value.from_address,
591 keys: value.keys,
592 data: value.data,
593 }
594 }
595}
596
597impl TryFrom<TransactionExecutionStatus> for core::TransactionExecutionStatus {
598 type Error = ConversionError;
599
600 fn try_from(value: TransactionExecutionStatus) -> Result<Self, Self::Error> {
601 match value {
602 TransactionExecutionStatus::Succeeded => Ok(Self::Succeeded),
603 TransactionExecutionStatus::Reverted => Ok(Self::Reverted),
604 TransactionExecutionStatus::Rejected => Err(ConversionError),
605 }
606 }
607}
608
609impl TryFrom<TransactionFinalityStatus> for core::TransactionFinalityStatus {
610 type Error = ConversionError;
611
612 fn try_from(value: TransactionFinalityStatus) -> Result<Self, Self::Error> {
613 match value {
614 TransactionFinalityStatus::NotReceived | TransactionFinalityStatus::Received => {
615 Err(ConversionError)
616 }
617 TransactionFinalityStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
618 TransactionFinalityStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
619 }
620 }
621}
622
623impl From<core::BroadcastedInvokeTransaction> for InvokeFunctionTransactionRequest {
624 fn from(value: core::BroadcastedInvokeTransaction) -> Self {
625 Self::V3(value.into())
626 }
627}
628
629impl From<core::BroadcastedInvokeTransactionV3> for InvokeFunctionV3TransactionRequest {
630 fn from(value: core::BroadcastedInvokeTransactionV3) -> Self {
631 Self {
632 sender_address: value.sender_address,
633 calldata: value.calldata,
634 signature: value.signature,
635 nonce: value.nonce,
636 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
637 fee_data_availability_mode: value.fee_data_availability_mode.into(),
638 resource_bounds: value.resource_bounds.into(),
639 tip: value.tip,
640 paymaster_data: value.paymaster_data,
641 account_deployment_data: value.account_deployment_data,
642 is_query: value.is_query,
643 }
644 }
645}
646
647impl TryFrom<core::BroadcastedDeclareTransaction> for DeclareTransactionRequest {
648 type Error = ConversionError;
649
650 fn try_from(value: core::BroadcastedDeclareTransaction) -> Result<Self, Self::Error> {
651 Ok(Self::V3(value.try_into()?))
652 }
653}
654
655impl TryFrom<core::BroadcastedDeclareTransactionV3> for DeclareV3TransactionRequest {
656 type Error = ConversionError;
657
658 fn try_from(value: core::BroadcastedDeclareTransactionV3) -> Result<Self, Self::Error> {
659 Ok(Self {
660 contract_class: Arc::new(
661 contract::CompressedSierraClass::from_flattened(&value.contract_class)
662 .map_err(|_| ConversionError)?,
663 ),
664 compiled_class_hash: value.compiled_class_hash,
665 sender_address: value.sender_address,
666 signature: value.signature,
667 nonce: value.nonce,
668 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
669 fee_data_availability_mode: value.fee_data_availability_mode.into(),
670 resource_bounds: value.resource_bounds.into(),
671 tip: value.tip,
672 paymaster_data: value.paymaster_data,
673 account_deployment_data: value.account_deployment_data,
674 is_query: value.is_query,
675 })
676 }
677}
678
679impl From<core::BroadcastedDeployAccountTransaction> for DeployAccountTransactionRequest {
680 fn from(value: core::BroadcastedDeployAccountTransaction) -> Self {
681 Self::V3(value.into())
682 }
683}
684
685impl From<core::BroadcastedDeployAccountTransactionV3> for DeployAccountV3TransactionRequest {
686 fn from(value: core::BroadcastedDeployAccountTransactionV3) -> Self {
687 Self {
688 class_hash: value.class_hash,
689 contract_address_salt: value.contract_address_salt,
690 constructor_calldata: value.constructor_calldata,
691 signature: value.signature,
692 nonce: value.nonce,
693 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
694 fee_data_availability_mode: value.fee_data_availability_mode.into(),
695 resource_bounds: value.resource_bounds.into(),
696 tip: value.tip,
697 paymaster_data: value.paymaster_data,
698 is_query: value.is_query,
699 }
700 }
701}
702
703impl From<core::CompressedLegacyContractClass> for CompressedLegacyContractClass {
704 fn from(value: core::CompressedLegacyContractClass) -> Self {
705 Self {
706 program: value.program,
707 entry_points_by_type: contract_legacy::RawLegacyEntryPoints {
708 constructor: value
709 .entry_points_by_type
710 .constructor
711 .into_iter()
712 .map(convert_legacy_entry_point)
713 .collect(),
714 external: value
715 .entry_points_by_type
716 .external
717 .into_iter()
718 .map(convert_legacy_entry_point)
719 .collect(),
720 l1_handler: value
721 .entry_points_by_type
722 .l1_handler
723 .into_iter()
724 .map(convert_legacy_entry_point)
725 .collect(),
726 },
727 abi: value
728 .abi
729 .map(|abi| abi.into_iter().map(|item| item.into()).collect()),
730 }
731 }
732}
733
734impl TryFrom<DeployedClass> for core::ContractClass {
735 type Error = ConversionError;
736
737 fn try_from(value: DeployedClass) -> Result<Self, Self::Error> {
738 match value {
739 DeployedClass::SierraClass(inner) => Ok(Self::Sierra(inner)),
740 DeployedClass::LegacyClass(inner) => {
741 Ok(Self::Legacy(inner.compress().map_err(|_| ConversionError)?))
742 }
743 }
744 }
745}
746
747impl From<EntryPointType> for core::EntryPointType {
748 fn from(value: EntryPointType) -> Self {
749 match value {
750 EntryPointType::External => Self::External,
751 EntryPointType::L1Handler => Self::L1Handler,
752 EntryPointType::Constructor => Self::Constructor,
753 }
754 }
755}
756
757impl TryFrom<TransactionStatusInfo> for core::TransactionStatus {
758 type Error = ConversionError;
759
760 fn try_from(value: TransactionStatusInfo) -> Result<Self, Self::Error> {
761 if value.status.is_rejected() {
762 return Err(ConversionError);
764 }
765
766 let exec_status = match value.execution_status.ok_or(ConversionError)? {
767 TransactionExecutionStatus::Succeeded => {
768 Some(core::TransactionExecutionStatus::Succeeded)
769 }
770 TransactionExecutionStatus::Reverted => {
771 Some(core::TransactionExecutionStatus::Reverted)
772 }
773 TransactionExecutionStatus::Rejected => None,
774 };
775
776 match value.finality_status {
777 Some(TransactionFinalityStatus::Received) => Ok(Self::Received),
778 Some(TransactionFinalityStatus::AcceptedOnL2) => {
779 let exec = match (
780 exec_status.ok_or(ConversionError)?,
781 value.transaction_failure_reason,
782 ) {
783 (core::TransactionExecutionStatus::Succeeded, None) => {
784 Ok(core::ExecutionResult::Succeeded)
785 }
786 (core::TransactionExecutionStatus::Reverted, Some(reason)) => {
787 Ok(core::ExecutionResult::Reverted {
788 reason: reason.error_message.unwrap_or(reason.code),
789 })
790 }
791 _ => Err(ConversionError),
792 };
793
794 Ok(Self::AcceptedOnL2(exec?))
795 }
796 Some(TransactionFinalityStatus::AcceptedOnL1) => {
797 let exec = match (
798 exec_status.ok_or(ConversionError)?,
799 value.transaction_failure_reason,
800 ) {
801 (core::TransactionExecutionStatus::Succeeded, None) => {
802 Ok(core::ExecutionResult::Succeeded)
803 }
804 (core::TransactionExecutionStatus::Reverted, Some(reason)) => {
805 Ok(core::ExecutionResult::Reverted {
806 reason: reason.error_message.unwrap_or(reason.code),
807 })
808 }
809 _ => Err(ConversionError),
810 };
811
812 Ok(Self::AcceptedOnL1(exec?))
813 }
814 _ => Err(ConversionError),
816 }
817 }
818}
819
820impl TryFrom<ConfirmedReceiptWithContext> for core::TransactionReceipt {
821 type Error = ConversionError;
822
823 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
824 match value.transaction {
825 TransactionType::Declare(_) => Ok(Self::Declare(value.try_into()?)),
826 TransactionType::Deploy(_) => Ok(Self::Deploy(value.try_into()?)),
827 TransactionType::DeployAccount(_) => Ok(Self::DeployAccount(value.try_into()?)),
828 TransactionType::InvokeFunction(_) => Ok(Self::Invoke(value.try_into()?)),
829 TransactionType::L1Handler(_) => Ok(Self::L1Handler(value.try_into()?)),
830 }
831 }
832}
833
834impl TryFrom<ConfirmedReceiptWithContext> for core::DeclareTransactionReceipt {
835 type Error = ConversionError;
836
837 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
838 Ok(Self {
839 transaction_hash: value.receipt.transaction_hash,
840 actual_fee: core::FeePayment {
841 amount: value.receipt.actual_fee,
842 unit: core::PriceUnit::Wei,
843 },
844 finality_status: value.finality.try_into()?,
845 messages_sent: value
846 .receipt
847 .l2_to_l1_messages
848 .into_iter()
849 .map(|item| item.into())
850 .collect(),
851 events: value
852 .receipt
853 .events
854 .into_iter()
855 .map(|item| item.into())
856 .collect(),
857 execution_resources: value
858 .receipt
859 .execution_resources
860 .ok_or(ConversionError)?
861 .total_gas_consumed
862 .ok_or(ConversionError)?,
863 execution_result: convert_execution_result(
864 value.receipt.execution_status,
865 value.receipt.revert_error,
866 )?,
867 })
868 }
869}
870
871impl TryFrom<ConfirmedReceiptWithContext> for core::DeployTransactionReceipt {
872 type Error = ConversionError;
873
874 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
875 Ok(Self {
876 transaction_hash: value.receipt.transaction_hash,
877 actual_fee: core::FeePayment {
878 amount: value.receipt.actual_fee,
879 unit: core::PriceUnit::Wei,
880 },
881 finality_status: value.finality.try_into()?,
882 messages_sent: value
883 .receipt
884 .l2_to_l1_messages
885 .into_iter()
886 .map(|item| item.into())
887 .collect(),
888 events: value
889 .receipt
890 .events
891 .into_iter()
892 .map(|item| item.into())
893 .collect(),
894 contract_address: match value.transaction {
895 TransactionType::Deploy(inner) => inner.contract_address,
896 _ => return Err(ConversionError),
897 },
898 execution_resources: value
899 .receipt
900 .execution_resources
901 .ok_or(ConversionError)?
902 .total_gas_consumed
903 .ok_or(ConversionError)?,
904 execution_result: convert_execution_result(
905 value.receipt.execution_status,
906 value.receipt.revert_error,
907 )?,
908 })
909 }
910}
911
912impl TryFrom<ConfirmedReceiptWithContext> for core::DeployAccountTransactionReceipt {
913 type Error = ConversionError;
914
915 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
916 Ok(Self {
917 transaction_hash: value.receipt.transaction_hash,
918 actual_fee: core::FeePayment {
919 amount: value.receipt.actual_fee,
920 unit: core::PriceUnit::Wei,
921 },
922 finality_status: value.finality.try_into()?,
923 messages_sent: value
924 .receipt
925 .l2_to_l1_messages
926 .into_iter()
927 .map(|item| item.into())
928 .collect(),
929 events: value
930 .receipt
931 .events
932 .into_iter()
933 .map(|item| item.into())
934 .collect(),
935 contract_address: match value.transaction {
936 TransactionType::DeployAccount(inner) => {
937 inner.contract_address.ok_or(ConversionError)?
938 }
939 _ => return Err(ConversionError),
940 },
941 execution_resources: value
942 .receipt
943 .execution_resources
944 .ok_or(ConversionError)?
945 .total_gas_consumed
946 .ok_or(ConversionError)?,
947 execution_result: convert_execution_result(
948 value.receipt.execution_status,
949 value.receipt.revert_error,
950 )?,
951 })
952 }
953}
954
955impl TryFrom<ConfirmedReceiptWithContext> for core::InvokeTransactionReceipt {
956 type Error = ConversionError;
957
958 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
959 Ok(Self {
960 transaction_hash: value.receipt.transaction_hash,
961 actual_fee: core::FeePayment {
962 amount: value.receipt.actual_fee,
963 unit: core::PriceUnit::Wei,
964 },
965 finality_status: value.finality.try_into()?,
966 messages_sent: value
967 .receipt
968 .l2_to_l1_messages
969 .into_iter()
970 .map(|item| item.into())
971 .collect(),
972 events: value
973 .receipt
974 .events
975 .into_iter()
976 .map(|item| item.into())
977 .collect(),
978 execution_resources: value
979 .receipt
980 .execution_resources
981 .ok_or(ConversionError)?
982 .total_gas_consumed
983 .ok_or(ConversionError)?,
984 execution_result: convert_execution_result(
985 value.receipt.execution_status,
986 value.receipt.revert_error,
987 )?,
988 })
989 }
990}
991
992impl TryFrom<ConfirmedReceiptWithContext> for core::L1HandlerTransactionReceipt {
993 type Error = ConversionError;
994
995 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
996 let l1_handler_tx: core::L1HandlerTransaction = match value.transaction {
998 TransactionType::L1Handler(tx) => tx.try_into().map_err(|_| ConversionError)?,
999 _ => return Err(ConversionError),
1000 };
1001 let msg_to_l2 = l1_handler_tx
1002 .parse_msg_to_l2()
1003 .map_err(|_| ConversionError)?;
1004
1005 Ok(Self {
1006 transaction_hash: value.receipt.transaction_hash,
1007 actual_fee: core::FeePayment {
1008 amount: value.receipt.actual_fee,
1009 unit: core::PriceUnit::Wei,
1010 },
1011 finality_status: value.finality.try_into()?,
1012 messages_sent: value
1013 .receipt
1014 .l2_to_l1_messages
1015 .into_iter()
1016 .map(|item| item.into())
1017 .collect(),
1018 events: value
1019 .receipt
1020 .events
1021 .into_iter()
1022 .map(|item| item.into())
1023 .collect(),
1024 execution_resources: value
1025 .receipt
1026 .execution_resources
1027 .ok_or(ConversionError)?
1028 .total_gas_consumed
1029 .ok_or(ConversionError)?,
1030 execution_result: convert_execution_result(
1031 value.receipt.execution_status,
1032 value.receipt.revert_error,
1033 )?,
1034 message_hash: msg_to_l2.hash(),
1035 })
1036 }
1037}
1038
1039impl TryFrom<BlockStatus> for core::TransactionFinalityStatus {
1040 type Error = ConversionError;
1041
1042 fn try_from(value: BlockStatus) -> Result<Self, Self::Error> {
1043 match value {
1044 BlockStatus::Pending | BlockStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
1046 BlockStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
1047 BlockStatus::Aborted | BlockStatus::Reverted => Err(ConversionError),
1048 }
1049 }
1050}
1051
1052fn convert_execution_result(
1053 execution_status: Option<TransactionExecutionStatus>,
1054 revert_error: Option<String>,
1055) -> Result<core::ExecutionResult, ConversionError> {
1056 match (execution_status, revert_error) {
1057 (None, None) => {
1058 Ok(core::ExecutionResult::Succeeded)
1066 }
1067 (Some(TransactionExecutionStatus::Succeeded), None) => Ok(core::ExecutionResult::Succeeded),
1068 (Some(TransactionExecutionStatus::Reverted), Some(revert_error)) => {
1069 Ok(core::ExecutionResult::Reverted {
1070 reason: revert_error,
1071 })
1072 }
1073 _ => Err(ConversionError),
1075 }
1076}
1077
1078const fn convert_legacy_entry_point(
1079 value: core::LegacyContractEntryPoint,
1080) -> contract_legacy::RawLegacyEntryPoint {
1081 contract_legacy::RawLegacyEntryPoint {
1084 offset: contract_legacy::LegacyEntrypointOffset::U64AsInt(value.offset),
1085 selector: value.selector,
1086 }
1087}