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