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 From<core::BlockId> for BlockId {
22 fn from(value: core::BlockId) -> Self {
23 match value {
24 core::BlockId::Hash(hash) => Self::Hash(hash),
25 core::BlockId::Number(num) => Self::Number(num),
26 core::BlockId::Tag(core::BlockTag::Latest) => Self::Latest,
27 core::BlockId::Tag(core::BlockTag::Pending) => Self::Pending,
28 }
29 }
30}
31
32impl TryFrom<Block> for core::MaybePendingBlockWithTxHashes {
33 type Error = ConversionError;
34
35 fn try_from(value: Block) -> Result<Self, Self::Error> {
36 match (value.block_hash, value.block_number, value.state_root) {
37 (Some(block_hash), Some(block_number), Some(state_root)) => {
39 Ok(Self::Block(core::BlockWithTxHashes {
40 status: value.status.try_into()?,
41 block_hash,
42 parent_hash: value.parent_block_hash,
43 block_number,
44 new_root: state_root,
45 timestamp: value.timestamp,
46 sequencer_address: value.sequencer_address.unwrap_or_default(),
47 l1_gas_price: value.l1_gas_price,
48 l2_gas_price: value.l2_gas_price,
49 l1_data_gas_price: value.l1_data_gas_price,
50 l1_da_mode: value.l1_da_mode,
51 starknet_version: value.starknet_version.ok_or(ConversionError)?,
52 transactions: value
53 .transactions
54 .iter()
55 .map(|tx| tx.transaction_hash())
56 .collect(),
57 }))
58 }
59 (None, None, None) => Ok(Self::PendingBlock(core::PendingBlockWithTxHashes {
61 transactions: value
62 .transactions
63 .iter()
64 .map(|tx| tx.transaction_hash())
65 .collect(),
66 timestamp: value.timestamp,
67 sequencer_address: value.sequencer_address.unwrap_or_default(),
68 parent_hash: value.parent_block_hash,
69 l1_gas_price: value.l1_gas_price,
70 l2_gas_price: value.l2_gas_price,
71 l1_data_gas_price: value.l1_data_gas_price,
72 l1_da_mode: value.l1_da_mode,
73 starknet_version: value.starknet_version.ok_or(ConversionError)?,
74 })),
75 _ => Err(ConversionError),
77 }
78 }
79}
80
81impl TryFrom<Block> for core::MaybePendingBlockWithTxs {
82 type Error = ConversionError;
83
84 fn try_from(value: Block) -> Result<Self, Self::Error> {
85 match (value.block_hash, value.block_number, value.state_root) {
86 (Some(block_hash), Some(block_number), Some(state_root)) => {
88 Ok(Self::Block(core::BlockWithTxs {
89 status: value.status.try_into()?,
90 block_hash,
91 parent_hash: value.parent_block_hash,
92 block_number,
93 new_root: state_root,
94 timestamp: value.timestamp,
95 sequencer_address: value.sequencer_address.unwrap_or_default(),
96 l1_gas_price: value.l1_gas_price,
97 l2_gas_price: value.l2_gas_price,
98 l1_data_gas_price: value.l1_data_gas_price,
99 l1_da_mode: value.l1_da_mode,
100 starknet_version: value.starknet_version.ok_or(ConversionError)?,
101 transactions: value
102 .transactions
103 .into_iter()
104 .map(|tx| tx.try_into())
105 .collect::<Result<_, _>>()?,
106 }))
107 }
108 (None, None, None) => Ok(Self::PendingBlock(core::PendingBlockWithTxs {
110 transactions: value
111 .transactions
112 .into_iter()
113 .map(|tx| tx.try_into())
114 .collect::<Result<_, _>>()?,
115 timestamp: value.timestamp,
116 sequencer_address: value.sequencer_address.unwrap_or_default(),
117 parent_hash: value.parent_block_hash,
118 l1_gas_price: value.l1_gas_price,
119 l2_gas_price: value.l2_gas_price,
120 l1_data_gas_price: value.l1_data_gas_price,
121 l1_da_mode: value.l1_da_mode,
122 starknet_version: value.starknet_version.ok_or(ConversionError)?,
123 })),
124 _ => Err(ConversionError),
126 }
127 }
128}
129
130impl TryFrom<Block> for core::MaybePendingBlockWithReceipts {
131 type Error = ConversionError;
132
133 fn try_from(value: Block) -> Result<Self, Self::Error> {
134 if value.transactions.len() != value.transaction_receipts.len() {
135 return Err(ConversionError);
136 }
137
138 let mut transactions = vec![];
139
140 for (tx, receipt) in value
141 .transactions
142 .into_iter()
143 .zip(value.transaction_receipts.into_iter())
144 {
145 let core_tx = tx.clone().try_into()?;
146
147 let tx_with_receipt = ConfirmedReceiptWithContext {
148 receipt,
149 transaction: tx,
150 finality: value.status,
151 };
152
153 transactions.push(core::TransactionWithReceipt {
154 transaction: core_tx,
155 receipt: tx_with_receipt.try_into()?,
156 });
157 }
158
159 match (value.block_hash, value.block_number, value.state_root) {
160 (Some(block_hash), Some(block_number), Some(state_root)) => {
162 Ok(Self::Block(core::BlockWithReceipts {
163 status: value.status.try_into()?,
164 block_hash,
165 parent_hash: value.parent_block_hash,
166 block_number,
167 new_root: state_root,
168 timestamp: value.timestamp,
169 sequencer_address: value.sequencer_address.unwrap_or_default(),
170 l1_gas_price: value.l1_gas_price,
171 l2_gas_price: value.l2_gas_price,
172 l1_data_gas_price: value.l1_data_gas_price,
173 l1_da_mode: value.l1_da_mode,
174 starknet_version: value.starknet_version.ok_or(ConversionError)?,
175 transactions,
176 }))
177 }
178 (None, None, None) => Ok(Self::PendingBlock(core::PendingBlockWithReceipts {
180 transactions,
181 timestamp: value.timestamp,
182 sequencer_address: value.sequencer_address.unwrap_or_default(),
183 parent_hash: value.parent_block_hash,
184 l1_gas_price: value.l1_gas_price,
185 l2_gas_price: value.l2_gas_price,
186 l1_data_gas_price: value.l1_data_gas_price,
187 l1_da_mode: value.l1_da_mode,
188 starknet_version: value.starknet_version.ok_or(ConversionError)?,
189 })),
190 _ => Err(ConversionError),
192 }
193 }
194}
195
196impl TryFrom<BlockStatus> for core::BlockStatus {
197 type Error = ConversionError;
198
199 fn try_from(value: BlockStatus) -> Result<Self, Self::Error> {
200 match value {
201 BlockStatus::Pending => Ok(Self::Pending),
202 BlockStatus::Aborted => Err(ConversionError),
203 BlockStatus::Reverted => Ok(Self::Rejected),
204 BlockStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
205 BlockStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
206 }
207 }
208}
209
210impl TryFrom<TransactionType> for core::Transaction {
211 type Error = ConversionError;
212
213 fn try_from(value: TransactionType) -> Result<Self, Self::Error> {
214 match value {
215 TransactionType::Declare(inner) => Ok(Self::Declare(inner.try_into()?)),
216 TransactionType::Deploy(inner) => Ok(Self::Deploy(inner.try_into()?)),
217 TransactionType::DeployAccount(inner) => Ok(Self::DeployAccount(inner.try_into()?)),
218 TransactionType::InvokeFunction(inner) => Ok(Self::Invoke(inner.try_into()?)),
219 TransactionType::L1Handler(inner) => Ok(Self::L1Handler(inner.try_into()?)),
220 }
221 }
222}
223
224impl TryFrom<TransactionType> for core::TransactionContent {
225 type Error = ConversionError;
226
227 fn try_from(value: TransactionType) -> Result<Self, Self::Error> {
228 let tx: core::Transaction = value.try_into()?;
229 Ok(tx.into())
230 }
231}
232
233impl TryFrom<DeclareTransaction> for core::DeclareTransaction {
234 type Error = ConversionError;
235
236 fn try_from(value: DeclareTransaction) -> Result<Self, Self::Error> {
237 if value.version == Felt::ZERO {
238 Ok(Self::V0(core::DeclareTransactionV0 {
239 transaction_hash: value.transaction_hash,
240 max_fee: value.max_fee.ok_or(ConversionError)?,
241 signature: value.signature,
242 class_hash: value.class_hash,
243 sender_address: value.sender_address,
244 }))
245 } else if value.version == Felt::ONE {
246 Ok(Self::V1(core::DeclareTransactionV1 {
247 transaction_hash: value.transaction_hash,
248 max_fee: value.max_fee.ok_or(ConversionError)?,
249 signature: value.signature,
250 nonce: value.nonce,
251 class_hash: value.class_hash,
252 sender_address: value.sender_address,
253 }))
254 } else if value.version == Felt::TWO {
255 Ok(Self::V2(core::DeclareTransactionV2 {
256 transaction_hash: value.transaction_hash,
257 max_fee: value.max_fee.ok_or(ConversionError)?,
258 signature: value.signature,
259 nonce: value.nonce,
260 class_hash: value.class_hash,
261 compiled_class_hash: value.compiled_class_hash.ok_or(ConversionError)?,
262 sender_address: value.sender_address,
263 }))
264 } else if value.version == Felt::THREE {
265 Ok(Self::V3(core::DeclareTransactionV3 {
266 transaction_hash: value.transaction_hash,
267 sender_address: value.sender_address,
268 compiled_class_hash: value.compiled_class_hash.ok_or(ConversionError)?,
269 signature: value.signature,
270 nonce: value.nonce,
271 class_hash: value.class_hash,
272 resource_bounds: value.resource_bounds.ok_or(ConversionError)?.into(),
273 tip: value.tip.ok_or(ConversionError)?,
274 paymaster_data: value.paymaster_data.ok_or(ConversionError)?,
275 account_deployment_data: value.account_deployment_data.ok_or(ConversionError)?,
276 nonce_data_availability_mode: value
277 .nonce_data_availability_mode
278 .ok_or(ConversionError)?
279 .into(),
280 fee_data_availability_mode: value
281 .fee_data_availability_mode
282 .ok_or(ConversionError)?
283 .into(),
284 }))
285 } else {
286 Err(ConversionError)
287 }
288 }
289}
290
291impl TryFrom<DeployTransaction> for core::DeployTransaction {
292 type Error = ConversionError;
293
294 fn try_from(value: DeployTransaction) -> Result<Self, Self::Error> {
295 Ok(Self {
296 transaction_hash: value.transaction_hash,
297 class_hash: value.class_hash,
298 version: value.version,
299 contract_address_salt: value.contract_address_salt,
300 constructor_calldata: value.constructor_calldata,
301 })
302 }
303}
304
305impl TryFrom<DeployAccountTransaction> for core::DeployAccountTransaction {
306 type Error = ConversionError;
307
308 fn try_from(value: DeployAccountTransaction) -> Result<Self, Self::Error> {
309 if value.version == Felt::ONE {
310 Ok(Self::V1(core::DeployAccountTransactionV1 {
311 transaction_hash: value.transaction_hash,
312 max_fee: value.max_fee.ok_or(ConversionError)?,
313 signature: value.signature,
314 nonce: value.nonce,
315 contract_address_salt: value.contract_address_salt,
316 constructor_calldata: value.constructor_calldata,
317 class_hash: value.class_hash,
318 }))
319 } else if value.version == Felt::THREE {
320 Ok(Self::V3(core::DeployAccountTransactionV3 {
321 transaction_hash: value.transaction_hash,
322 signature: value.signature,
323 nonce: value.nonce,
324 contract_address_salt: value.contract_address_salt,
325 constructor_calldata: value.constructor_calldata,
326 class_hash: value.class_hash,
327 resource_bounds: value.resource_bounds.ok_or(ConversionError)?.into(),
328 tip: value.tip.ok_or(ConversionError)?,
329 paymaster_data: value.paymaster_data.ok_or(ConversionError)?,
330 nonce_data_availability_mode: value
331 .nonce_data_availability_mode
332 .ok_or(ConversionError)?
333 .into(),
334 fee_data_availability_mode: value
335 .fee_data_availability_mode
336 .ok_or(ConversionError)?
337 .into(),
338 }))
339 } else {
340 Err(ConversionError)
341 }
342 }
343}
344
345impl TryFrom<InvokeFunctionTransaction> for core::InvokeTransaction {
346 type Error = ConversionError;
347
348 fn try_from(value: InvokeFunctionTransaction) -> Result<Self, Self::Error> {
349 if value.version == Felt::ZERO {
350 Ok(Self::V0(core::InvokeTransactionV0 {
351 transaction_hash: value.transaction_hash,
352 max_fee: value.max_fee.ok_or(ConversionError)?,
353 signature: value.signature,
354 contract_address: value.sender_address,
355 entry_point_selector: value.entry_point_selector.ok_or(ConversionError)?,
356 calldata: value.calldata,
357 }))
358 } else if value.version == Felt::ONE {
359 Ok(Self::V1(core::InvokeTransactionV1 {
360 transaction_hash: value.transaction_hash,
361 max_fee: value.max_fee.ok_or(ConversionError)?,
362 signature: value.signature,
363 nonce: value.nonce.ok_or(ConversionError)?,
364 sender_address: value.sender_address,
365 calldata: value.calldata,
366 }))
367 } else if value.version == Felt::THREE {
368 Ok(Self::V3(core::InvokeTransactionV3 {
369 transaction_hash: value.transaction_hash,
370 sender_address: value.sender_address,
371 calldata: value.calldata,
372 signature: value.signature,
373 nonce: value.nonce.ok_or(ConversionError)?,
374 resource_bounds: value.resource_bounds.ok_or(ConversionError)?.into(),
375 tip: value.tip.ok_or(ConversionError)?,
376 paymaster_data: value.paymaster_data.ok_or(ConversionError)?,
377 account_deployment_data: value.account_deployment_data.ok_or(ConversionError)?,
378 nonce_data_availability_mode: value
379 .nonce_data_availability_mode
380 .ok_or(ConversionError)?
381 .into(),
382 fee_data_availability_mode: value
383 .fee_data_availability_mode
384 .ok_or(ConversionError)?
385 .into(),
386 }))
387 } else {
388 Err(ConversionError)
389 }
390 }
391}
392
393impl TryFrom<L1HandlerTransaction> for core::L1HandlerTransaction {
394 type Error = ConversionError;
395
396 fn try_from(value: L1HandlerTransaction) -> Result<Self, Self::Error> {
397 Ok(Self {
398 transaction_hash: value.transaction_hash,
399 version: value.version,
400 nonce: {
401 let nonce_bytes = value.nonce.unwrap_or_default().to_bytes_le();
403 if nonce_bytes.iter().skip(8).any(|&x| x != 0) {
404 return Err(ConversionError);
405 }
406 u64::from_le_bytes(nonce_bytes[..8].try_into().unwrap())
407 },
408 contract_address: value.contract_address,
409 entry_point_selector: value.entry_point_selector,
410 calldata: value.calldata,
411 })
412 }
413}
414
415impl From<ResourceBoundsMapping> for core::ResourceBoundsMapping {
416 fn from(value: ResourceBoundsMapping) -> Self {
417 Self {
418 l1_gas: value.l1_gas.into(),
419 l1_data_gas: value.l1_data_gas.into(),
420 l2_gas: value.l2_gas.into(),
421 }
422 }
423}
424
425impl From<core::ResourceBoundsMapping> for ResourceBoundsMapping {
426 fn from(value: core::ResourceBoundsMapping) -> Self {
427 Self {
428 l1_gas: value.l1_gas.into(),
429 l1_data_gas: value.l1_data_gas.into(),
430 l2_gas: value.l2_gas.into(),
431 }
432 }
433}
434
435impl From<ResourceBounds> for core::ResourceBounds {
436 fn from(value: ResourceBounds) -> Self {
437 Self {
438 max_amount: value.max_amount,
439 max_price_per_unit: value.max_price_per_unit,
440 }
441 }
442}
443
444impl From<core::ResourceBounds> for ResourceBounds {
445 fn from(value: core::ResourceBounds) -> Self {
446 Self {
447 max_amount: value.max_amount,
448 max_price_per_unit: value.max_price_per_unit,
449 }
450 }
451}
452
453impl From<DataAvailabilityMode> for core::DataAvailabilityMode {
454 fn from(value: DataAvailabilityMode) -> Self {
455 match value {
456 DataAvailabilityMode::L1 => Self::L1,
457 DataAvailabilityMode::L2 => Self::L2,
458 }
459 }
460}
461
462impl From<core::DataAvailabilityMode> for DataAvailabilityMode {
463 fn from(value: core::DataAvailabilityMode) -> Self {
464 match value {
465 core::DataAvailabilityMode::L1 => Self::L1,
466 core::DataAvailabilityMode::L2 => Self::L2,
467 }
468 }
469}
470
471impl TryFrom<StateUpdate> for core::MaybePendingStateUpdate {
472 type Error = ConversionError;
473
474 fn try_from(value: StateUpdate) -> Result<Self, Self::Error> {
475 match (value.block_hash, value.new_root) {
476 (Some(block_hash), Some(new_root)) => Ok(Self::Update(core::StateUpdate {
477 block_hash,
478 new_root,
479 old_root: value.old_root,
480 state_diff: value.state_diff.into(),
481 })),
482 (None, None) => Ok(Self::PendingUpdate(core::PendingStateUpdate {
483 old_root: value.old_root,
484 state_diff: value.state_diff.into(),
485 })),
486 _ => Err(ConversionError),
487 }
488 }
489}
490
491impl From<StateDiff> for core::StateDiff {
492 fn from(value: StateDiff) -> Self {
493 Self {
494 storage_diffs: value
495 .storage_diffs
496 .into_iter()
497 .map(|(key, value)| core::ContractStorageDiffItem {
498 address: key,
499 storage_entries: value.into_iter().map(|item| item.into()).collect(),
500 })
501 .collect(),
502 deprecated_declared_classes: value.old_declared_contracts,
503 declared_classes: value
504 .declared_classes
505 .into_iter()
506 .map(|item| item.into())
507 .collect(),
508 deployed_contracts: value
509 .deployed_contracts
510 .into_iter()
511 .map(|item| item.into())
512 .collect(),
513 replaced_classes: value
514 .replaced_classes
515 .into_iter()
516 .map(|item| item.into())
517 .collect(),
518 nonces: value
519 .nonces
520 .into_iter()
521 .map(|(key, value)| core::NonceUpdate {
522 contract_address: key,
523 nonce: value,
524 })
525 .collect(),
526 }
527 }
528}
529
530impl From<StorageDiff> for core::StorageEntry {
531 fn from(value: StorageDiff) -> Self {
532 Self {
533 key: value.key,
534 value: value.value,
535 }
536 }
537}
538
539impl From<DeclaredContract> for core::DeclaredClassItem {
540 fn from(value: DeclaredContract) -> Self {
541 Self {
542 class_hash: value.class_hash,
543 compiled_class_hash: value.compiled_class_hash,
544 }
545 }
546}
547
548impl From<DeployedContract> for core::DeployedContractItem {
549 fn from(value: DeployedContract) -> Self {
550 Self {
551 address: value.address,
552 class_hash: value.class_hash,
553 }
554 }
555}
556
557impl From<DeployedContract> for core::ReplacedClassItem {
558 fn from(value: DeployedContract) -> Self {
559 Self {
560 contract_address: value.address,
561 class_hash: value.class_hash,
562 }
563 }
564}
565
566impl TryFrom<TransactionInfo> for core::Transaction {
567 type Error = ConversionError;
568
569 fn try_from(value: TransactionInfo) -> Result<Self, Self::Error> {
570 match value.r#type {
571 Some(tx) => tx.try_into(),
572 None => Err(ConversionError),
573 }
574 }
575}
576
577impl From<L2ToL1Message> for core::MsgToL1 {
578 fn from(value: L2ToL1Message) -> Self {
579 Self {
580 from_address: value.from_address,
581 to_address: Felt::from_bytes_be_slice(&value.to_address.0),
583 payload: value.payload,
584 }
585 }
586}
587
588impl From<Event> for core::Event {
589 fn from(value: Event) -> Self {
590 Self {
591 from_address: value.from_address,
592 keys: value.keys,
593 data: value.data,
594 }
595 }
596}
597
598impl TryFrom<TransactionExecutionStatus> for core::TransactionExecutionStatus {
599 type Error = ConversionError;
600
601 fn try_from(value: TransactionExecutionStatus) -> Result<Self, Self::Error> {
602 match value {
603 TransactionExecutionStatus::Succeeded => Ok(Self::Succeeded),
604 TransactionExecutionStatus::Reverted => Ok(Self::Reverted),
605 TransactionExecutionStatus::Rejected => Err(ConversionError),
606 }
607 }
608}
609
610impl TryFrom<TransactionFinalityStatus> for core::TransactionFinalityStatus {
611 type Error = ConversionError;
612
613 fn try_from(value: TransactionFinalityStatus) -> Result<Self, Self::Error> {
614 match value {
615 TransactionFinalityStatus::NotReceived | TransactionFinalityStatus::Received => {
616 Err(ConversionError)
617 }
618 TransactionFinalityStatus::AcceptedOnL2 => Ok(Self::AcceptedOnL2),
619 TransactionFinalityStatus::AcceptedOnL1 => Ok(Self::AcceptedOnL1),
620 }
621 }
622}
623
624impl From<core::BroadcastedInvokeTransaction> for InvokeFunctionTransactionRequest {
625 fn from(value: core::BroadcastedInvokeTransaction) -> Self {
626 Self::V3(value.into())
627 }
628}
629
630impl From<core::BroadcastedInvokeTransactionV3> for InvokeFunctionV3TransactionRequest {
631 fn from(value: core::BroadcastedInvokeTransactionV3) -> Self {
632 Self {
633 sender_address: value.sender_address,
634 calldata: value.calldata,
635 signature: value.signature,
636 nonce: value.nonce,
637 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
638 fee_data_availability_mode: value.fee_data_availability_mode.into(),
639 resource_bounds: value.resource_bounds.into(),
640 tip: value.tip,
641 paymaster_data: value.paymaster_data,
642 account_deployment_data: value.account_deployment_data,
643 is_query: value.is_query,
644 }
645 }
646}
647
648impl TryFrom<core::BroadcastedDeclareTransaction> for DeclareTransactionRequest {
649 type Error = ConversionError;
650
651 fn try_from(value: core::BroadcastedDeclareTransaction) -> Result<Self, Self::Error> {
652 Ok(Self::V3(value.try_into()?))
653 }
654}
655
656impl TryFrom<core::BroadcastedDeclareTransactionV3> for DeclareV3TransactionRequest {
657 type Error = ConversionError;
658
659 fn try_from(value: core::BroadcastedDeclareTransactionV3) -> Result<Self, Self::Error> {
660 Ok(Self {
661 contract_class: Arc::new(
662 contract::CompressedSierraClass::from_flattened(&value.contract_class)
663 .map_err(|_| ConversionError)?,
664 ),
665 compiled_class_hash: value.compiled_class_hash,
666 sender_address: value.sender_address,
667 signature: value.signature,
668 nonce: value.nonce,
669 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
670 fee_data_availability_mode: value.fee_data_availability_mode.into(),
671 resource_bounds: value.resource_bounds.into(),
672 tip: value.tip,
673 paymaster_data: value.paymaster_data,
674 account_deployment_data: value.account_deployment_data,
675 is_query: value.is_query,
676 })
677 }
678}
679
680impl From<core::BroadcastedDeployAccountTransaction> for DeployAccountTransactionRequest {
681 fn from(value: core::BroadcastedDeployAccountTransaction) -> Self {
682 Self::V3(value.into())
683 }
684}
685
686impl From<core::BroadcastedDeployAccountTransactionV3> for DeployAccountV3TransactionRequest {
687 fn from(value: core::BroadcastedDeployAccountTransactionV3) -> Self {
688 Self {
689 class_hash: value.class_hash,
690 contract_address_salt: value.contract_address_salt,
691 constructor_calldata: value.constructor_calldata,
692 signature: value.signature,
693 nonce: value.nonce,
694 nonce_data_availability_mode: value.nonce_data_availability_mode.into(),
695 fee_data_availability_mode: value.fee_data_availability_mode.into(),
696 resource_bounds: value.resource_bounds.into(),
697 tip: value.tip,
698 paymaster_data: value.paymaster_data,
699 is_query: value.is_query,
700 }
701 }
702}
703
704impl From<core::CompressedLegacyContractClass> for CompressedLegacyContractClass {
705 fn from(value: core::CompressedLegacyContractClass) -> Self {
706 Self {
707 program: value.program,
708 entry_points_by_type: contract_legacy::RawLegacyEntryPoints {
709 constructor: value
710 .entry_points_by_type
711 .constructor
712 .into_iter()
713 .map(convert_legacy_entry_point)
714 .collect(),
715 external: value
716 .entry_points_by_type
717 .external
718 .into_iter()
719 .map(convert_legacy_entry_point)
720 .collect(),
721 l1_handler: value
722 .entry_points_by_type
723 .l1_handler
724 .into_iter()
725 .map(convert_legacy_entry_point)
726 .collect(),
727 },
728 abi: value
729 .abi
730 .map(|abi| abi.into_iter().map(|item| item.into()).collect()),
731 }
732 }
733}
734
735impl TryFrom<DeployedClass> for core::ContractClass {
736 type Error = ConversionError;
737
738 fn try_from(value: DeployedClass) -> Result<Self, Self::Error> {
739 match value {
740 DeployedClass::SierraClass(inner) => Ok(Self::Sierra(inner)),
741 DeployedClass::LegacyClass(inner) => {
742 Ok(Self::Legacy(inner.compress().map_err(|_| ConversionError)?))
743 }
744 }
745 }
746}
747
748impl From<EntryPointType> for core::EntryPointType {
749 fn from(value: EntryPointType) -> Self {
750 match value {
751 EntryPointType::External => Self::External,
752 EntryPointType::L1Handler => Self::L1Handler,
753 EntryPointType::Constructor => Self::Constructor,
754 }
755 }
756}
757
758impl TryFrom<TransactionStatusInfo> for core::TransactionStatus {
759 type Error = ConversionError;
760
761 fn try_from(value: TransactionStatusInfo) -> Result<Self, Self::Error> {
762 if value.status.is_rejected() {
763 return Ok(Self::Rejected);
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}