starknet_devnet_types/rpc/
messaging.rs

1use serde::{Deserialize, Serialize};
2use starknet_rs_core::types::{EthAddress, Felt, Hash256, MsgToL1, MsgToL2};
3
4use crate::contract_address::ContractAddress;
5use crate::error::{DevnetResult, Error};
6use crate::felt::{Calldata, EntryPointSelector, Nonce, try_felt_to_num};
7use crate::rpc::eth_address::EthAddressWrapper;
8
9/// An L1 to L2 message.
10#[derive(Debug, Clone, Deserialize, Serialize)]
11#[serde(deny_unknown_fields)]
12#[cfg_attr(feature = "testing", derive(PartialEq, Eq))]
13pub struct MessageToL2 {
14    pub l1_transaction_hash: Option<Hash256>,
15    pub l2_contract_address: ContractAddress,
16    pub entry_point_selector: EntryPointSelector,
17    pub l1_contract_address: ContractAddress,
18    pub payload: Calldata,
19    pub paid_fee_on_l1: Felt,
20    pub nonce: Nonce,
21}
22
23impl MessageToL2 {
24    pub fn hash(&self) -> DevnetResult<Hash256> {
25        let msg_to_l2 = MsgToL2 {
26            from_address: EthAddress::from_felt(&self.l1_contract_address.into()).map_err(
27                |err| {
28                    Error::ConversionError(crate::error::ConversionError::OutOfRangeError(
29                        err.to_string(),
30                    ))
31                },
32            )?,
33            to_address: self.l2_contract_address.into(),
34            selector: self.entry_point_selector,
35            payload: self.payload.clone(),
36            nonce: try_felt_to_num::<u64>(self.nonce).map_err(|err| {
37                Error::ConversionError(crate::error::ConversionError::OutOfRangeError(
38                    err.to_string(),
39                ))
40            })?,
41        };
42
43        Ok(msg_to_l2.hash())
44    }
45}
46
47pub type L2ToL1Payload = Vec<Felt>;
48
49/// An L2 to L1 message.
50#[derive(Debug, Clone, Deserialize, Serialize)]
51#[serde(deny_unknown_fields)]
52pub struct MessageToL1 {
53    pub from_address: ContractAddress,
54    pub to_address: EthAddressWrapper,
55    pub payload: L2ToL1Payload,
56}
57
58impl MessageToL1 {
59    /// Computes the hash of a `MessageToL1`.
60    /// Re-uses the already tested hash computation
61    /// from starknet-rs.
62    pub fn hash(&self) -> Hash256 {
63        let msg_to_l1 = MsgToL1 {
64            from_address: self.from_address.into(),
65            to_address: self.to_address.inner.clone().into(),
66            payload: self.payload.clone(),
67        };
68
69        msg_to_l1.hash()
70    }
71}
72
73#[derive(Debug, Clone, Deserialize, Serialize)]
74#[serde(deny_unknown_fields)]
75pub struct OrderedMessageToL1 {
76    pub order: usize,
77    #[serde(flatten)]
78    pub message: MessageToL1,
79}
80
81impl OrderedMessageToL1 {
82    pub fn new(
83        msg: &blockifier::execution::call_info::OrderedL2ToL1Message,
84        from_address: ContractAddress,
85    ) -> DevnetResult<Self> {
86        Ok(Self {
87            order: msg.order,
88            message: MessageToL1 {
89                from_address,
90                to_address: msg.message.to_address.try_into()?,
91                payload: msg.message.payload.0.clone(),
92            },
93        })
94    }
95}