Skip to content

Commit eff2d26

Browse files
committed
feat: add types for v0.10.0 RPC
1 parent fb30030 commit eff2d26

File tree

10 files changed

+364
-2
lines changed

10 files changed

+364
-2
lines changed

madara/crates/primitives/block/src/event_with_info.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ impl From<EventWithInfo> for mp_rpc::v0_7_1::EmittedEvent {
4040
}
4141
}
4242

43+
impl From<EventWithInfo> for mp_rpc::v0_10_0::EmittedEvent {
44+
fn from(event_with_info: EventWithInfo) -> Self {
45+
mp_rpc::v0_10_0::EmittedEvent {
46+
event: event_with_info.event.into(),
47+
block_hash: event_with_info.block_hash,
48+
// v0_10_0 expects None when the event is in the pending block.
49+
block_number: if event_with_info.in_preconfirmed { None } else { Some(event_with_info.block_number) },
50+
transaction_hash: event_with_info.transaction_hash,
51+
transaction_index: event_with_info.transaction_index,
52+
event_index: event_with_info.event_index_in_block,
53+
}
54+
}
55+
}
56+
4357
/// Filters events based on the provided address and keys.
4458
///
4559
/// This function checks if an event matches the given address and keys.

madara/crates/primitives/chain_config/src/rpc_version.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use std::hash::Hash;
22
use std::str::FromStr;
33

4-
const SUPPORTED_RPC_VERSIONS: [RpcVersion; 4] = [
4+
const SUPPORTED_RPC_VERSIONS: [RpcVersion; 5] = [
55
RpcVersion::RPC_VERSION_0_7_1,
66
RpcVersion::RPC_VERSION_0_8_1,
77
RpcVersion::RPC_VERSION_0_9_0,
8+
RpcVersion::RPC_VERSION_0_10_0,
89
RpcVersion::RPC_VERSION_ADMIN_0_1_0,
910
];
1011

@@ -86,7 +87,8 @@ impl RpcVersion {
8687
pub const RPC_VERSION_0_7_1: RpcVersion = RpcVersion([0, 7, 1]);
8788
pub const RPC_VERSION_0_8_1: RpcVersion = RpcVersion([0, 8, 1]);
8889
pub const RPC_VERSION_0_9_0: RpcVersion = RpcVersion([0, 9, 0]);
89-
pub const RPC_VERSION_LATEST: RpcVersion = Self::RPC_VERSION_0_9_0;
90+
pub const RPC_VERSION_0_10_0: RpcVersion = RpcVersion([0, 10, 0]);
91+
pub const RPC_VERSION_LATEST: RpcVersion = Self::RPC_VERSION_0_10_0;
9092

9193
pub const RPC_VERSION_ADMIN_0_1_0: RpcVersion = RpcVersion([0, 1, 0]);
9294
pub const RPC_VERSION_LATEST_ADMIN: RpcVersion = Self::RPC_VERSION_ADMIN_0_1_0;

madara/crates/primitives/gateway/src/state_update.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ impl From<StateDiff> for mp_state_update::StateDiff {
102102
.into_iter()
103103
.map(|(contract_address, nonce)| mp_state_update::NonceUpdate { contract_address, nonce })
104104
.collect(),
105+
migrated_compiled_classes: vec![], // TODO(prakhar,22/11/2025): Add migrated compiled classes here
105106
}
106107
}
107108
}

madara/crates/primitives/rpc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pub mod admin;
44
pub mod v0_7_1;
55
pub mod v0_8_1;
66
pub mod v0_9_0;
7+
pub mod v0_10_0;
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//! v0.10.0 of the API.
2+
mod starknet_api_openrpc;
3+
mod starknet_trace_api_openrpc;
4+
mod starknet_ws_api;
5+
6+
pub use self::starknet_api_openrpc::*;
7+
pub use self::starknet_trace_api_openrpc::*;
8+
pub use self::starknet_ws_api::*;
9+
10+
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
11+
pub enum BlockId {
12+
/// The tag of the block.
13+
Tag(BlockTag),
14+
/// The hash of the block.
15+
Hash(BlockHash),
16+
/// The height of the block.
17+
Number(BlockNumber),
18+
}
19+
20+
impl serde::Serialize for BlockId {
21+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
22+
where
23+
S: serde::Serializer,
24+
{
25+
match self {
26+
BlockId::Tag(tag) => tag.serialize(serializer),
27+
BlockId::Hash(block_hash) => BlockHashHelper { block_hash: *block_hash }.serialize(serializer),
28+
BlockId::Number(block_number) => BlockNumberHelper { block_number: *block_number }.serialize(serializer),
29+
}
30+
}
31+
}
32+
33+
impl<'de> serde::Deserialize<'de> for BlockId {
34+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
35+
where
36+
D: serde::de::Deserializer<'de>,
37+
{
38+
let helper = BlockIdHelper::deserialize(deserializer)?;
39+
match helper {
40+
BlockIdHelper::Tag(tag) => Ok(BlockId::Tag(tag)),
41+
BlockIdHelper::Hash(helper) => Ok(BlockId::Hash(helper.block_hash)),
42+
BlockIdHelper::Number(helper) => Ok(BlockId::Number(helper.block_number)),
43+
}
44+
}
45+
}
46+
47+
#[derive(serde::Deserialize)]
48+
#[serde(untagged)]
49+
enum BlockIdHelper {
50+
Tag(BlockTag),
51+
Hash(BlockHashHelper),
52+
Number(BlockNumberHelper),
53+
}
54+
55+
#[test]
56+
fn block_id_from_hash() {
57+
pub use starknet_types_core::felt::Felt;
58+
59+
let s = "{\"block_hash\":\"0x123\"}";
60+
let block_id: BlockId = serde_json::from_str(s).unwrap();
61+
assert_eq!(block_id, BlockId::Hash(Felt::from_hex("0x123").unwrap()));
62+
}
63+
64+
#[test]
65+
fn block_id_from_number() {
66+
let s = "{\"block_number\":123}";
67+
let block_id: BlockId = serde_json::from_str(s).unwrap();
68+
assert_eq!(block_id, BlockId::Number(123));
69+
}
70+
71+
#[test]
72+
fn block_id_from_latest() {
73+
let s = "\"latest\"";
74+
let block_id: BlockId = serde_json::from_str(s).unwrap();
75+
assert_eq!(block_id, BlockId::Tag(BlockTag::Latest));
76+
}
77+
78+
#[test]
79+
fn block_id_from_pre_confirmed() {
80+
let s = "\"pre_confirmed\"";
81+
let block_id: BlockId = serde_json::from_str(s).unwrap();
82+
assert_eq!(block_id, BlockId::Tag(BlockTag::PreConfirmed));
83+
}
84+
85+
#[test]
86+
fn block_id_from_l1_accepted() {
87+
let s = "\"l1_accepted\"";
88+
let block_id: BlockId = serde_json::from_str(s).unwrap();
89+
assert_eq!(block_id, BlockId::Tag(BlockTag::L1Accepted));
90+
}
91+
92+
#[cfg(test)]
93+
#[test]
94+
fn block_id_to_hash() {
95+
pub use starknet_types_core::felt::Felt;
96+
97+
let block_id = BlockId::Hash(Felt::from_hex("0x123").unwrap());
98+
let s = serde_json::to_string(&block_id).unwrap();
99+
assert_eq!(s, "{\"block_hash\":\"0x123\"}");
100+
}
101+
102+
#[cfg(test)]
103+
#[test]
104+
fn block_id_to_number() {
105+
let block_id = BlockId::Number(123);
106+
let s = serde_json::to_string(&block_id).unwrap();
107+
assert_eq!(s, "{\"block_number\":123}");
108+
}
109+
110+
#[cfg(test)]
111+
#[test]
112+
fn block_id_to_latest() {
113+
let block_id = BlockId::Tag(BlockTag::Latest);
114+
let s = serde_json::to_string(&block_id).unwrap();
115+
assert_eq!(s, "\"latest\"");
116+
}
117+
118+
#[cfg(test)]
119+
#[test]
120+
fn block_id_to_pre_confirmed() {
121+
let block_id = BlockId::Tag(BlockTag::PreConfirmed);
122+
let s = serde_json::to_string(&block_id).unwrap();
123+
assert_eq!(s, "\"pre_confirmed\"");
124+
}
125+
126+
#[cfg(test)]
127+
#[test]
128+
fn block_id_to_l1_accepted() {
129+
let block_id = BlockId::Tag(BlockTag::L1Accepted);
130+
let s = serde_json::to_string(&block_id).unwrap();
131+
assert_eq!(s, "\"l1_accepted\"");
132+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
pub use crate::v0_9_0::{
2+
AddDeclareTransactionParams, AddDeployAccountTransactionParams, AddInvokeTransactionParams,
3+
AddInvokeTransactionResult, Address, BlockHash, BlockHashAndNumber, BlockHashAndNumberParams, BlockHashHelper,
4+
BlockHeader, BlockNumber, BlockNumberHelper, BlockNumberParams, BlockStatus, BlockTag, BlockWithReceipts,
5+
BlockWithTxHashes, BlockWithTxs, BroadcastedDeclareTxn, BroadcastedDeclareTxnV1, BroadcastedDeclareTxnV2,
6+
BroadcastedDeclareTxnV3, BroadcastedDeployAccountTxn, BroadcastedInvokeTxn, BroadcastedTxn, CallParams,
7+
ChainId, ChainIdParams, ClassAndTxnHash, CommonReceiptProperties, ContractAbi, ContractAbiEntry,
8+
ContractAndTxnHash, ContractClass, ContractLeavesDataItem, ContractStorageDiffItem,
9+
ContractsProof, DaMode, DataAvailability, DeclareTxn, DeclareTxnReceipt, DeclareTxnV0, DeclareTxnV1,
10+
DeclareTxnV2, DeclareTxnV3, DeployAccountTxn, DeployAccountTxnReceipt, DeployAccountTxnV1, DeployAccountTxnV3,
11+
DeployTxn, DeployTxnReceipt, DeployedContractItem, DeprecatedCairoEntryPoint, DeprecatedContractClass,
12+
DeprecatedEntryPointsByType, EntryPointsByType, EstimateFeeParams, EstimateMessageFeeParams, EthAddress,
13+
Event, EventAbiEntry, EventAbiType, EventContent, EventFilterWithPageRequest, EventsChunk, ExecutionResources,
14+
ExecutionStatus, FeeEstimate, FeeEstimateCommon, FeePayment, FunctionAbiEntry, FunctionAbiType, FunctionCall, FunctionStateMutability,
15+
GetBlockTransactionCountParams, GetBlockWithReceiptsParams, GetBlockWithTxHashesParams, GetBlockWithTxsParams,
16+
GetClassAtParams, GetClassHashAtParams, GetClassParams, GetEventsParams, GetNonceParams, GetStateUpdateParams,
17+
GetStorageAtParams, GetStorageProofResult, GetTransactionByBlockIdAndIndexParams, GetTransactionByHashParams,
18+
GetTransactionReceiptParams, GetTransactionStatusParams, GlobalRoots, InvokeTxn, InvokeTxnReceipt,
19+
InvokeTxnV0, InvokeTxnV1, InvokeTxnV3, KeyValuePair, L1DaMode, L1HandlerTxn, L1HandlerTxnReceipt,
20+
MaybeDeprecatedContractClass, MaybePreConfirmedBlockWithTxHashes, MaybePreConfirmedBlockWithTxs,
21+
MessageFeeEstimate,
22+
MerkleNode, MsgFromL1, MsgToL1, NewClasses, NodeHashToNodeMappingItem, NonceUpdate, PriceUnitFri, PriceUnitWei,
23+
PreConfirmedBlockHeader, PreConfirmedBlockWithReceipts, PreConfirmedBlockWithTxHashes,
24+
PreConfirmedBlockWithTxs, ReplacedClass, ResourceBounds, ResourceBoundsMapping, ResourcePrice,
25+
SierraEntryPoint, Signature, SimulationFlagForEstimateFee, SpecVersionParams, StateUpdate, StorageKey,
26+
StarknetGetBlockWithTxsAndReceiptsResult, StructAbiEntry, StructAbiType, StructMember, SyncStatus,
27+
SyncingParams, SyncingStatus, TransactionAndReceipt, Txn, TxnExecutionStatus, TxnFinalityAndExecutionStatus,
28+
TxnFinalityStatus, TxnHash, TxnReceipt, TxnReceiptWithBlockInfo, TxnStatus, TxnWithHash, TypedParameter,
29+
};
30+
use serde::{Deserialize, Serialize};
31+
use starknet_types_core::felt::Felt;
32+
33+
/// RPC 0.10.0 Changes:
34+
/// 1. StateDiff: Added `migrated_compiled_classes` field
35+
/// 2. PreConfirmedStateUpdate: Removed `old_root` field
36+
/// 3. EmittedEvent: Added `transaction_index` and `event_index` fields
37+
/// 4. ContractStorageKeysItem: Changed `storage_keys` type from `Vec<Felt>` to `Vec<StorageKey>`
38+
39+
/// The change in state applied in this block, given as a mapping of addresses to the new values and/or new contracts
40+
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
41+
pub struct StateDiff {
42+
/// The declared class hash and compiled class hash
43+
pub declared_classes: Vec<NewClasses>,
44+
/// The deployed contracts
45+
pub deployed_contracts: Vec<DeployedContractItem>,
46+
/// The hash of the declared class
47+
pub deprecated_declared_classes: Vec<Felt>,
48+
/// The nonce updates
49+
pub nonces: Vec<NonceUpdate>,
50+
/// The replaced classes
51+
pub replaced_classes: Vec<ReplacedClass>,
52+
/// The storage diffs
53+
pub storage_diffs: Vec<ContractStorageDiffItem>,
54+
/// The migrated compiled classes (NEW in v0.10.0)
55+
pub migrated_compiled_classes: Vec<MigratedClassItem>,
56+
}
57+
58+
/// A migrated class item representing a class that was migrated from Poseidon to BLAKE hash
59+
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
60+
pub struct MigratedClassItem {
61+
/// The hash of the declared class
62+
pub class_hash: Felt,
63+
/// The new BLAKE hash (post-SNIP-34)
64+
pub compiled_class_hash: Felt,
65+
}
66+
67+
#[derive(Eq, Hash, PartialEq, Serialize, Deserialize, Clone, Debug)]
68+
#[serde(untagged)]
69+
pub enum MaybePreConfirmedStateUpdate {
70+
Block(StateUpdate),
71+
PreConfirmed(PreConfirmedStateUpdate),
72+
}
73+
74+
/// Pre-confirmed state update (v0.10.0: removed `old_root` field)
75+
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
76+
pub struct PreConfirmedStateUpdate {
77+
/// The state diff
78+
pub state_diff: StateDiff,
79+
}
80+
81+
/// An event emitted as part of a transaction (v0.10.0: added transaction_index and event_index)
82+
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
83+
pub struct EmittedEvent {
84+
/// The event information
85+
#[serde(flatten)]
86+
pub event: Event,
87+
/// The hash of the block in which the event was emitted
88+
#[serde(default)]
89+
pub block_hash: Option<BlockHash>,
90+
/// The number of the block in which the event was emitted
91+
#[serde(default)]
92+
pub block_number: Option<BlockNumber>,
93+
/// The transaction that emitted the event
94+
pub transaction_hash: TxnHash,
95+
/// The index of the transaction within the block
96+
pub transaction_index: u64,
97+
/// The index of the event within the transaction
98+
pub event_index: u64,
99+
}
100+
101+
/// Contract storage keys item (v0.10.0: changed storage_keys type from Vec<Felt> to Vec<StorageKey>)
102+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
103+
pub struct ContractStorageKeysItem {
104+
/// The address of the contract
105+
pub contract_address: Felt,
106+
/// The storage keys (changed from Vec<Felt> to Vec<StorageKey> in v0.10.0)
107+
pub storage_keys: Vec<StorageKey>,
108+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pub use crate::v0_9_0::{
2+
CallType, DeclareTransactionTrace, DeployAccountTransactionTrace, EntryPointType,
3+
InvokeTransactionTrace, L1HandlerTransactionTrace, OrderedEvent, OrderedMessage,
4+
RevertedInvocation, RevertibleFunctionInvocation, SimulationFlag, SimulateTransactionsResult,
5+
TraceBlockTransactionsResult, TraceTransactionResult, TransactionTrace,
6+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use serde::{Deserialize, Serialize};
2+
3+
use super::{EmittedEvent, TxnFinalityStatus};
4+
5+
pub use crate::v0_9_0::FinalityStatus;
6+
7+
/// An emitted event with finality status for WebSocket subscriptions
8+
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
9+
pub struct EmittedEventWithFinality {
10+
#[serde(flatten)]
11+
pub emitted_event: EmittedEvent,
12+
#[serde(flatten)]
13+
pub finality_status: TxnFinalityStatus,
14+
}

madara/crates/primitives/state_update/src/into_starknet_types.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ impl From<mp_rpc::v0_7_1::StateDiff> for StateDiff {
5858
.map(|replaced_class| replaced_class.into())
5959
.collect(),
6060
nonces: state_diff.nonces.into_iter().map(|nonce| nonce.into()).collect(),
61+
migrated_compiled_classes: vec![], // v0.7.1 doesn't have migrated classes
6162
}
6263
}
6364
}
@@ -171,6 +172,61 @@ impl From<NonceUpdate> for mp_rpc::v0_7_1::NonceUpdate {
171172
}
172173
}
173174

175+
// v0.10.0 conversions
176+
impl From<StateDiff> for mp_rpc::v0_10_0::StateDiff {
177+
fn from(state_diff: StateDiff) -> Self {
178+
Self {
179+
storage_diffs: state_diff
180+
.storage_diffs
181+
.into_iter()
182+
.map(|diff| mp_rpc::v0_10_0::ContractStorageDiffItem {
183+
address: diff.address,
184+
storage_entries: diff
185+
.storage_entries
186+
.into_iter()
187+
.map(|entry| mp_rpc::v0_10_0::KeyValuePair { key: entry.key, value: entry.value })
188+
.collect(),
189+
})
190+
.collect(),
191+
deprecated_declared_classes: state_diff.old_declared_contracts,
192+
declared_classes: state_diff
193+
.declared_classes
194+
.into_iter()
195+
.map(|item| mp_rpc::v0_10_0::NewClasses {
196+
class_hash: item.class_hash,
197+
compiled_class_hash: item.compiled_class_hash,
198+
})
199+
.collect(),
200+
deployed_contracts: state_diff
201+
.deployed_contracts
202+
.into_iter()
203+
.map(|item| mp_rpc::v0_10_0::DeployedContractItem { address: item.address, class_hash: item.class_hash })
204+
.collect(),
205+
replaced_classes: state_diff
206+
.replaced_classes
207+
.into_iter()
208+
.map(|item| mp_rpc::v0_10_0::ReplacedClass {
209+
contract_address: item.contract_address,
210+
class_hash: item.class_hash,
211+
})
212+
.collect(),
213+
nonces: state_diff
214+
.nonces
215+
.into_iter()
216+
.map(|item| mp_rpc::v0_10_0::NonceUpdate { contract_address: item.contract_address, nonce: item.nonce })
217+
.collect(),
218+
migrated_compiled_classes: state_diff
219+
.migrated_compiled_classes
220+
.into_iter()
221+
.map(|item| mp_rpc::v0_10_0::MigratedClassItem {
222+
class_hash: item.class_hash,
223+
compiled_class_hash: item.compiled_class_hash,
224+
})
225+
.collect(),
226+
}
227+
}
228+
}
229+
174230
#[cfg(test)]
175231
mod test {
176232
use super::*;

0 commit comments

Comments
 (0)