1use std::sync::Arc;
2
3use starknet_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) {
461 (Some(block_hash), Some(new_root)) => Ok(Self::Update(core::StateUpdate {
462 block_hash,
463 new_root,
464 old_root: value.old_root,
465 state_diff: value.state_diff.into(),
466 })),
467 (None, None) => Ok(Self::PreConfirmedUpdate(core::PreConfirmedStateUpdate {
468 old_root: value.old_root,
469 state_diff: value.state_diff.into(),
470 })),
471 _ => Err(ConversionError),
472 }
473 }
474}
475
476impl From<StateDiff> for core::StateDiff {
477 fn from(value: StateDiff) -> Self {
478 Self {
479 storage_diffs: value
480 .storage_diffs
481 .into_iter()
482 .map(|(key, value)| core::ContractStorageDiffItem {
483 address: key,
484 storage_entries: value.into_iter().map(|item| item.into()).collect(),
485 })
486 .collect(),
487 deprecated_declared_classes: value.old_declared_contracts,
488 declared_classes: value
489 .declared_classes
490 .into_iter()
491 .map(|item| item.into())
492 .collect(),
493 deployed_contracts: value
494 .deployed_contracts
495 .into_iter()
496 .map(|item| item.into())
497 .collect(),
498 replaced_classes: value
499 .replaced_classes
500 .into_iter()
501 .map(|item| item.into())
502 .collect(),
503 nonces: value
504 .nonces
505 .into_iter()
506 .map(|(key, value)| core::NonceUpdate {
507 contract_address: key,
508 nonce: value,
509 })
510 .collect(),
511 }
512 }
513}
514
515impl From<StorageDiff> for core::StorageEntry {
516 fn from(value: StorageDiff) -> Self {
517 Self {
518 key: value.key,
519 value: value.value,
520 }
521 }
522}
523
524impl From<DeclaredContract> for core::DeclaredClassItem {
525 fn from(value: DeclaredContract) -> Self {
526 Self {
527 class_hash: value.class_hash,
528 compiled_class_hash: value.compiled_class_hash,
529 }
530 }
531}
532
533impl From<DeployedContract> for core::DeployedContractItem {
534 fn from(value: DeployedContract) -> Self {
535 Self {
536 address: value.address,
537 class_hash: value.class_hash,
538 }
539 }
540}
541
542impl From<DeployedContract> for core::ReplacedClassItem {
543 fn from(value: DeployedContract) -> Self {
544 Self {
545 contract_address: value.address,
546 class_hash: value.class_hash,
547 }
548 }
549}
550
551impl TryFrom<TransactionInfo> for core::Transaction {
552 type Error = ConversionError;
553
554 fn try_from(value: TransactionInfo) -> Result<Self, Self::Error> {
555 match value.r#type {
556 Some(tx) => tx.try_into(),
557 None => Err(ConversionError),
558 }
559 }
560}
561
562impl From<L2ToL1Message> for core::MsgToL1 {
563 fn from(value: L2ToL1Message) -> Self {
564 Self {
565 from_address: value.from_address,
566 to_address: Felt::from_bytes_be_slice(&value.to_address.0),
568 payload: value.payload,
569 }
570 }
571}
572
573impl From<Event> for core::Event {
574 fn from(value: Event) -> Self {
575 Self {
576 from_address: value.from_address,
577 keys: value.keys,
578 data: value.data,
579 }
580 }
581}
582
583impl TryFrom<TransactionExecutionStatus> for core::TransactionExecutionStatus {
584 type Error = ConversionError;
585
586 fn try_from(value: TransactionExecutionStatus) -> Result<Self, Self::Error> {
587 match value {
588 TransactionExecutionStatus::Succeeded => Ok(Self::Succeeded),
589 TransactionExecutionStatus::Reverted => Ok(Self::Reverted),
590 TransactionExecutionStatus::Rejected => Err(ConversionError),
591 }
592 }
593}
594
595impl TryFrom<TransactionFinalityStatus> for core::TransactionFinalityStatus {
596 type Error = ConversionError;
597
598 fn try_from(value: TransactionFinalityStatus) -> Result<Self, Self::Error> {
599 match value {
600 TransactionFinalityStatus::NotReceived | TransactionFinalityStatus::Received => {
601 Err(ConversionError)
602 }
603 TransactionFinalityStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
604 TransactionFinalityStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
605 }
606 }
607}
608
609impl From<core::BroadcastedInvokeTransaction> for InvokeFunctionTransactionRequest {
610 fn from(value: core::BroadcastedInvokeTransaction) -> Self {
611 Self::V3(value.into())
612 }
613}
614
615impl From<core::BroadcastedInvokeTransactionV3> for InvokeFunctionV3TransactionRequest {
616 fn from(value: core::BroadcastedInvokeTransactionV3) -> Self {
617 Self {
618 sender_address: value.sender_address,
619 calldata: value.calldata,
620 signature: value.signature,
621 nonce: value.nonce,
622 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
623 fee_data_availability_mode: value.fee_data_availability_mode.into(),
624 resource_bounds: value.resource_bounds.into(),
625 tip: value.tip,
626 paymaster_data: value.paymaster_data,
627 account_deployment_data: value.account_deployment_data,
628 is_query: value.is_query,
629 }
630 }
631}
632
633impl TryFrom<core::BroadcastedDeclareTransaction> for DeclareTransactionRequest {
634 type Error = ConversionError;
635
636 fn try_from(value: core::BroadcastedDeclareTransaction) -> Result<Self, Self::Error> {
637 Ok(Self::V3(value.try_into()?))
638 }
639}
640
641impl TryFrom<core::BroadcastedDeclareTransactionV3> for DeclareV3TransactionRequest {
642 type Error = ConversionError;
643
644 fn try_from(value: core::BroadcastedDeclareTransactionV3) -> Result<Self, Self::Error> {
645 Ok(Self {
646 contract_class: Arc::new(
647 contract::CompressedSierraClass::from_flattened(&value.contract_class)
648 .map_err(|_| ConversionError)?,
649 ),
650 compiled_class_hash: value.compiled_class_hash,
651 sender_address: value.sender_address,
652 signature: value.signature,
653 nonce: value.nonce,
654 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
655 fee_data_availability_mode: value.fee_data_availability_mode.into(),
656 resource_bounds: value.resource_bounds.into(),
657 tip: value.tip,
658 paymaster_data: value.paymaster_data,
659 account_deployment_data: value.account_deployment_data,
660 is_query: value.is_query,
661 })
662 }
663}
664
665impl From<core::BroadcastedDeployAccountTransaction> for DeployAccountTransactionRequest {
666 fn from(value: core::BroadcastedDeployAccountTransaction) -> Self {
667 Self::V3(value.into())
668 }
669}
670
671impl From<core::BroadcastedDeployAccountTransactionV3> for DeployAccountV3TransactionRequest {
672 fn from(value: core::BroadcastedDeployAccountTransactionV3) -> Self {
673 Self {
674 class_hash: value.class_hash,
675 contract_address_salt: value.contract_address_salt,
676 constructor_calldata: value.constructor_calldata,
677 signature: value.signature,
678 nonce: value.nonce,
679 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
680 fee_data_availability_mode: value.fee_data_availability_mode.into(),
681 resource_bounds: value.resource_bounds.into(),
682 tip: value.tip,
683 paymaster_data: value.paymaster_data,
684 is_query: value.is_query,
685 }
686 }
687}
688
689impl From<core::CompressedLegacyContractClass> for CompressedLegacyContractClass {
690 fn from(value: core::CompressedLegacyContractClass) -> Self {
691 Self {
692 program: value.program,
693 entry_points_by_type: contract_legacy::RawLegacyEntryPoints {
694 constructor: value
695 .entry_points_by_type
696 .constructor
697 .into_iter()
698 .map(convert_legacy_entry_point)
699 .collect(),
700 external: value
701 .entry_points_by_type
702 .external
703 .into_iter()
704 .map(convert_legacy_entry_point)
705 .collect(),
706 l1_handler: value
707 .entry_points_by_type
708 .l1_handler
709 .into_iter()
710 .map(convert_legacy_entry_point)
711 .collect(),
712 },
713 abi: value
714 .abi
715 .map(|abi| abi.into_iter().map(|item| item.into()).collect()),
716 }
717 }
718}
719
720impl TryFrom<DeployedClass> for core::ContractClass {
721 type Error = ConversionError;
722
723 fn try_from(value: DeployedClass) -> Result<Self, Self::Error> {
724 match value {
725 DeployedClass::SierraClass(inner) => Ok(Self::Sierra(inner)),
726 DeployedClass::LegacyClass(inner) => {
727 Ok(Self::Legacy(inner.compress().map_err(|_| ConversionError)?))
728 }
729 }
730 }
731}
732
733impl From<EntryPointType> for core::EntryPointType {
734 fn from(value: EntryPointType) -> Self {
735 match value {
736 EntryPointType::External => Self::External,
737 EntryPointType::L1Handler => Self::L1Handler,
738 EntryPointType::Constructor => Self::Constructor,
739 }
740 }
741}
742
743impl TryFrom<TransactionStatusInfo> for core::TransactionStatus {
744 type Error = ConversionError;
745
746 fn try_from(value: TransactionStatusInfo) -> Result<Self, Self::Error> {
747 if value.status.is_rejected() {
748 return Err(ConversionError);
750 }
751
752 let exec_status = match value.execution_status.ok_or(ConversionError)? {
753 TransactionExecutionStatus::Succeeded => {
754 Some(core::TransactionExecutionStatus::Succeeded)
755 }
756 TransactionExecutionStatus::Reverted => {
757 Some(core::TransactionExecutionStatus::Reverted)
758 }
759 TransactionExecutionStatus::Rejected => None,
760 };
761
762 match value.finality_status {
763 Some(TransactionFinalityStatus::Received) => Ok(Self::Received),
764 Some(TransactionFinalityStatus::AcceptedOnL2) => {
765 let exec = match (
766 exec_status.ok_or(ConversionError)?,
767 value.transaction_failure_reason,
768 ) {
769 (core::TransactionExecutionStatus::Succeeded, None) => {
770 Ok(core::ExecutionResult::Succeeded)
771 }
772 (core::TransactionExecutionStatus::Reverted, Some(reason)) => {
773 Ok(core::ExecutionResult::Reverted {
774 reason: reason.error_message.unwrap_or(reason.code),
775 })
776 }
777 _ => Err(ConversionError),
778 };
779
780 Ok(Self::AcceptedOnL2(exec?))
781 }
782 Some(TransactionFinalityStatus::AcceptedOnL1) => {
783 let exec = match (
784 exec_status.ok_or(ConversionError)?,
785 value.transaction_failure_reason,
786 ) {
787 (core::TransactionExecutionStatus::Succeeded, None) => {
788 Ok(core::ExecutionResult::Succeeded)
789 }
790 (core::TransactionExecutionStatus::Reverted, Some(reason)) => {
791 Ok(core::ExecutionResult::Reverted {
792 reason: reason.error_message.unwrap_or(reason.code),
793 })
794 }
795 _ => Err(ConversionError),
796 };
797
798 Ok(Self::AcceptedOnL1(exec?))
799 }
800 _ => Err(ConversionError),
802 }
803 }
804}
805
806impl TryFrom<ConfirmedReceiptWithContext> for core::TransactionReceipt {
807 type Error = ConversionError;
808
809 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
810 match value.transaction {
811 TransactionType::Declare(_) => Ok(Self::Declare(value.try_into()?)),
812 TransactionType::Deploy(_) => Ok(Self::Deploy(value.try_into()?)),
813 TransactionType::DeployAccount(_) => Ok(Self::DeployAccount(value.try_into()?)),
814 TransactionType::InvokeFunction(_) => Ok(Self::Invoke(value.try_into()?)),
815 TransactionType::L1Handler(_) => Ok(Self::L1Handler(value.try_into()?)),
816 }
817 }
818}
819
820impl TryFrom<ConfirmedReceiptWithContext> for core::DeclareTransactionReceipt {
821 type Error = ConversionError;
822
823 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
824 Ok(Self {
825 transaction_hash: value.receipt.transaction_hash,
826 actual_fee: core::FeePayment {
827 amount: value.receipt.actual_fee,
828 unit: core::PriceUnit::Wei,
829 },
830 finality_status: value.finality.try_into()?,
831 messages_sent: value
832 .receipt
833 .l2_to_l1_messages
834 .into_iter()
835 .map(|item| item.into())
836 .collect(),
837 events: value
838 .receipt
839 .events
840 .into_iter()
841 .map(|item| item.into())
842 .collect(),
843 execution_resources: value
844 .receipt
845 .execution_resources
846 .ok_or(ConversionError)?
847 .total_gas_consumed
848 .ok_or(ConversionError)?,
849 execution_result: convert_execution_result(
850 value.receipt.execution_status,
851 value.receipt.revert_error,
852 )?,
853 })
854 }
855}
856
857impl TryFrom<ConfirmedReceiptWithContext> for core::DeployTransactionReceipt {
858 type Error = ConversionError;
859
860 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
861 Ok(Self {
862 transaction_hash: value.receipt.transaction_hash,
863 actual_fee: core::FeePayment {
864 amount: value.receipt.actual_fee,
865 unit: core::PriceUnit::Wei,
866 },
867 finality_status: value.finality.try_into()?,
868 messages_sent: value
869 .receipt
870 .l2_to_l1_messages
871 .into_iter()
872 .map(|item| item.into())
873 .collect(),
874 events: value
875 .receipt
876 .events
877 .into_iter()
878 .map(|item| item.into())
879 .collect(),
880 contract_address: match value.transaction {
881 TransactionType::Deploy(inner) => inner.contract_address,
882 _ => return Err(ConversionError),
883 },
884 execution_resources: value
885 .receipt
886 .execution_resources
887 .ok_or(ConversionError)?
888 .total_gas_consumed
889 .ok_or(ConversionError)?,
890 execution_result: convert_execution_result(
891 value.receipt.execution_status,
892 value.receipt.revert_error,
893 )?,
894 })
895 }
896}
897
898impl TryFrom<ConfirmedReceiptWithContext> for core::DeployAccountTransactionReceipt {
899 type Error = ConversionError;
900
901 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
902 Ok(Self {
903 transaction_hash: value.receipt.transaction_hash,
904 actual_fee: core::FeePayment {
905 amount: value.receipt.actual_fee,
906 unit: core::PriceUnit::Wei,
907 },
908 finality_status: value.finality.try_into()?,
909 messages_sent: value
910 .receipt
911 .l2_to_l1_messages
912 .into_iter()
913 .map(|item| item.into())
914 .collect(),
915 events: value
916 .receipt
917 .events
918 .into_iter()
919 .map(|item| item.into())
920 .collect(),
921 contract_address: match value.transaction {
922 TransactionType::DeployAccount(inner) => {
923 inner.contract_address.ok_or(ConversionError)?
924 }
925 _ => return Err(ConversionError),
926 },
927 execution_resources: value
928 .receipt
929 .execution_resources
930 .ok_or(ConversionError)?
931 .total_gas_consumed
932 .ok_or(ConversionError)?,
933 execution_result: convert_execution_result(
934 value.receipt.execution_status,
935 value.receipt.revert_error,
936 )?,
937 })
938 }
939}
940
941impl TryFrom<ConfirmedReceiptWithContext> for core::InvokeTransactionReceipt {
942 type Error = ConversionError;
943
944 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
945 Ok(Self {
946 transaction_hash: value.receipt.transaction_hash,
947 actual_fee: core::FeePayment {
948 amount: value.receipt.actual_fee,
949 unit: core::PriceUnit::Wei,
950 },
951 finality_status: value.finality.try_into()?,
952 messages_sent: value
953 .receipt
954 .l2_to_l1_messages
955 .into_iter()
956 .map(|item| item.into())
957 .collect(),
958 events: value
959 .receipt
960 .events
961 .into_iter()
962 .map(|item| item.into())
963 .collect(),
964 execution_resources: value
965 .receipt
966 .execution_resources
967 .ok_or(ConversionError)?
968 .total_gas_consumed
969 .ok_or(ConversionError)?,
970 execution_result: convert_execution_result(
971 value.receipt.execution_status,
972 value.receipt.revert_error,
973 )?,
974 })
975 }
976}
977
978impl TryFrom<ConfirmedReceiptWithContext> for core::L1HandlerTransactionReceipt {
979 type Error = ConversionError;
980
981 fn try_from(value: ConfirmedReceiptWithContext) -> Result<Self, Self::Error> {
982 let l1_handler_tx: core::L1HandlerTransaction = match value.transaction {
984 TransactionType::L1Handler(tx) => tx.try_into().map_err(|_| ConversionError)?,
985 _ => return Err(ConversionError),
986 };
987 let msg_to_l2 = l1_handler_tx
988 .parse_msg_to_l2()
989 .map_err(|_| ConversionError)?;
990
991 Ok(Self {
992 transaction_hash: value.receipt.transaction_hash,
993 actual_fee: core::FeePayment {
994 amount: value.receipt.actual_fee,
995 unit: core::PriceUnit::Wei,
996 },
997 finality_status: value.finality.try_into()?,
998 messages_sent: value
999 .receipt
1000 .l2_to_l1_messages
1001 .into_iter()
1002 .map(|item| item.into())
1003 .collect(),
1004 events: value
1005 .receipt
1006 .events
1007 .into_iter()
1008 .map(|item| item.into())
1009 .collect(),
1010 execution_resources: value
1011 .receipt
1012 .execution_resources
1013 .ok_or(ConversionError)?
1014 .total_gas_consumed
1015 .ok_or(ConversionError)?,
1016 execution_result: convert_execution_result(
1017 value.receipt.execution_status,
1018 value.receipt.revert_error,
1019 )?,
1020 message_hash: msg_to_l2.hash(),
1021 })
1022 }
1023}
1024
1025impl TryFrom<BlockStatus> for core::TransactionFinalityStatus {
1026 type Error = ConversionError;
1027
1028 fn try_from(value: BlockStatus) -> Result<Self, Self::Error> {
1029 match value {
1030 BlockStatus::Pending | BlockStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
1032 BlockStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
1033 BlockStatus::Aborted | BlockStatus::Reverted => Err(ConversionError),
1034 }
1035 }
1036}
1037
1038fn convert_execution_result(
1039 execution_status: Option<TransactionExecutionStatus>,
1040 revert_error: Option<String>,
1041) -> Result<core::ExecutionResult, ConversionError> {
1042 match (execution_status, revert_error) {
1043 (None, None) => {
1044 Ok(core::ExecutionResult::Succeeded)
1052 }
1053 (Some(TransactionExecutionStatus::Succeeded), None) => Ok(core::ExecutionResult::Succeeded),
1054 (Some(TransactionExecutionStatus::Reverted), Some(revert_error)) => {
1055 Ok(core::ExecutionResult::Reverted {
1056 reason: revert_error,
1057 })
1058 }
1059 _ => Err(ConversionError),
1061 }
1062}
1063
1064const fn convert_legacy_entry_point(
1065 value: core::LegacyContractEntryPoint,
1066) -> contract_legacy::RawLegacyEntryPoint {
1067 contract_legacy::RawLegacyEntryPoint {
1070 offset: contract_legacy::LegacyEntrypointOffset::U64AsInt(value.offset),
1071 selector: value.selector,
1072 }
1073}