From f799a9383705db7b5d95c2f428fb7fbe6775d84c Mon Sep 17 00:00:00 2001 From: glihm Date: Mon, 28 Oct 2024 15:17:02 -0600 Subject: [PATCH 1/2] feat: add event selector for event structs --- contracts/src/gen.cairo | 13 +++++++++++++ crates/rs/src/expand/event.rs | 17 ++++------------- crates/rs/src/expand/struct.rs | 28 +++++++++++++++++++++++++--- crates/rs/src/expand/utils.rs | 4 ++++ examples/structs.rs | 10 ++++++++++ 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/contracts/src/gen.cairo b/contracts/src/gen.cairo index b449be4..6f33872 100644 --- a/contracts/src/gen.cairo +++ b/contracts/src/gen.cairo @@ -8,6 +8,19 @@ mod gen { v2: felt252, } + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + E1: E1, + } + + #[derive(Drop, starknet::Event)] + struct E1 { + #[key] + key: felt252, + value: Span, + } + #[derive(Serde, Drop)] struct PlainStruct { f1: u8, diff --git a/crates/rs/src/expand/event.rs b/crates/rs/src/expand/event.rs index d1149c3..364bc49 100644 --- a/crates/rs/src/expand/event.rs +++ b/crates/rs/src/expand/event.rs @@ -40,17 +40,6 @@ impl CairoEnumEvent { } } } - - // TODO: - // For each enum in enums -> check if it's an event. - // if yes -> - // 1. impl a function to retrieve the selector + string name of the event. - // 2. impl `TryFrom` EmittedEvent. Need to take in account the new flat keyword. - // - if nested => the selector is the name of the enum variant. - // - if nested and the type it points to is also an enum => first selector is - // the name of the variant of the current enum, and then we've to check - // recursively until the event type is a struct and not an enum. - // - if it's flat, we just take the name of the current variant. } pub fn expand_event_enum( @@ -65,6 +54,8 @@ impl CairoEnumEvent { let event_name_str = composite.type_name_or_alias(); let event_name = utils::str_to_ident(&composite.type_name_or_alias()); + let snrs_utils = utils::snrs_utils(); + for variant in &composite.inners { let selector_key_offset = utils::str_to_litint(&depth.to_string()); @@ -117,7 +108,7 @@ impl CairoEnumEvent { quote! { let selector = event.keys[#selector_key_offset]; - if selector == starknet::core::utils::get_selector_from_name(#variant_name_str).unwrap_or_else(|_| panic!("Invalid selector for {}", #variant_name_str)) { + if selector == #snrs_utils::get_selector_from_name(#variant_name_str).unwrap_or_else(|_| panic!("Invalid selector for {}", #variant_name_str)) { #inner_content } } @@ -143,7 +134,7 @@ impl CairoEnumEvent { quote! { let selector = event.keys[#selector_key_offset]; - if selector == starknet::core::utils::get_selector_from_name(#variant_name_str).unwrap_or_else(|_| panic!("Invalid selector for {}", #variant_name_str)) { + if selector == #snrs_utils::get_selector_from_name(#variant_name_str).unwrap_or_else(|_| panic!("Invalid selector for {}", #variant_name_str)) { let mut key_offset = #selector_key_offset + 1; let mut data_offset = 0; diff --git a/crates/rs/src/expand/struct.rs b/crates/rs/src/expand/struct.rs index 7b952ba..230999a 100644 --- a/crates/rs/src/expand/struct.rs +++ b/crates/rs/src/expand/struct.rs @@ -78,6 +78,7 @@ impl CairoStruct { } let struct_name = utils::str_to_ident(&composite.type_name_or_alias()); + let struct_name_str = utils::str_to_litstr(&composite.type_name_or_alias()); let mut sizes: Vec = vec![]; let mut sers: Vec = vec![]; @@ -154,6 +155,25 @@ impl CairoStruct { } let ccs = utils::cainome_cairo_serde(); + let snrs_types = utils::snrs_types(); + let snrs_utils = utils::snrs_utils(); + + let event_impl = if composite.is_event { + quote! { + impl #struct_name { + pub fn selector() -> #snrs_types::Felt { + // Ok to unwrap since the event name comes from the ABI, which is already validated. + #snrs_utils::get_selector_from_name(#struct_name_str).unwrap() + } + + pub fn event_name() -> &'static str { + #struct_name_str + } + } + } + } else { + quote!() + }; let (impl_line, rust_type) = if composite.is_generic() { let gen_args: Vec = composite @@ -189,13 +209,13 @@ impl CairoStruct { __size } - fn cairo_serialize(__rust: &Self::RustType) -> Vec { - let mut __out: Vec = vec![]; + fn cairo_serialize(__rust: &Self::RustType) -> Vec<#snrs_types::Felt> { + let mut __out: Vec<#snrs_types::Felt> = vec![]; #(#sers)* __out } - fn cairo_deserialize(__felts: &[starknet::core::types::Felt], __offset: usize) -> #ccs::Result { + fn cairo_deserialize(__felts: &[#snrs_types::Felt], __offset: usize) -> #ccs::Result { let mut __offset = __offset; #(#desers)* Ok(#struct_name { @@ -203,6 +223,8 @@ impl CairoStruct { }) } } + + #event_impl } } } diff --git a/crates/rs/src/expand/utils.rs b/crates/rs/src/expand/utils.rs index c7e2be2..46d8fbb 100644 --- a/crates/rs/src/expand/utils.rs +++ b/crates/rs/src/expand/utils.rs @@ -23,6 +23,10 @@ pub fn snrs_types() -> Type { str_to_type("starknet::core::types") } +pub fn snrs_utils() -> Type { + str_to_type("starknet::core::utils") +} + pub fn snrs_accounts() -> Type { str_to_type("starknet::accounts") } diff --git a/examples/structs.rs b/examples/structs.rs index 815bd4f..134e04b 100644 --- a/examples/structs.rs +++ b/examples/structs.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use cainome::rs::abigen; use paste::paste; use starknet::core::types::Felt; @@ -27,6 +29,14 @@ macro_rules! test_enum { #[tokio::main] async fn main() { + assert_eq!( + E1::selector(), + Felt::from_str("0x00ba2026c84b59ce46a4007300eb97e3e275d4119261ee402d7a3eb40ad58807") + .unwrap() + ); + + assert_eq!(E1::event_name(), "E1"); + let s = PlainStruct { f1: 1, f2: 2, From 28cbe527580e6bc5773f8215cb3aa6bce2db57ee Mon Sep 17 00:00:00 2001 From: glihm Date: Mon, 28 Oct 2024 15:20:03 -0600 Subject: [PATCH 2/2] fix: rename to event_selector --- crates/rs/src/expand/struct.rs | 2 +- examples/structs.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rs/src/expand/struct.rs b/crates/rs/src/expand/struct.rs index 230999a..d1e9e40 100644 --- a/crates/rs/src/expand/struct.rs +++ b/crates/rs/src/expand/struct.rs @@ -161,7 +161,7 @@ impl CairoStruct { let event_impl = if composite.is_event { quote! { impl #struct_name { - pub fn selector() -> #snrs_types::Felt { + pub fn event_selector() -> #snrs_types::Felt { // Ok to unwrap since the event name comes from the ABI, which is already validated. #snrs_utils::get_selector_from_name(#struct_name_str).unwrap() } diff --git a/examples/structs.rs b/examples/structs.rs index 134e04b..1fa6aad 100644 --- a/examples/structs.rs +++ b/examples/structs.rs @@ -30,7 +30,7 @@ macro_rules! test_enum { #[tokio::main] async fn main() { assert_eq!( - E1::selector(), + E1::event_selector(), Felt::from_str("0x00ba2026c84b59ce46a4007300eb97e3e275d4119261ee402d7a3eb40ad58807") .unwrap() );