Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions spel-client-gen/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ fn test_pda_helpers_single_arg_seed() {
spec: None,
metadata: None,
instruction_type: None,
events: vec![],
};

let output = generate_pda_helpers(&idl);
Expand Down Expand Up @@ -352,6 +353,7 @@ fn test_pda_helpers_multi_seed() {
spec: None,
metadata: None,
instruction_type: None,
events: vec![],
};

let output = generate_pda_helpers(&idl);
Expand Down Expand Up @@ -433,6 +435,7 @@ fn test_pda_helpers_deduplication() {
spec: None,
metadata: None,
instruction_type: None,
events: vec![],
};

let output = generate_pda_helpers(&idl);
Expand Down Expand Up @@ -507,6 +510,7 @@ fn test_pda_helpers_u64_single_seed() {
spec: None,
metadata: None,
instruction_type: None,
events: vec![],
};

let output = generate_pda_helpers(&idl);
Expand Down Expand Up @@ -595,6 +599,7 @@ fn test_pda_helpers_u64_multi_seed() {
spec: None,
metadata: None,
instruction_type: None,
events: vec![],
};

let output = generate_pda_helpers(&idl);
Expand Down
15 changes: 15 additions & 0 deletions spel-framework-core/src/idl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ pub struct SpelIdl {
/// Example: "multisig_core::Instruction"
#[serde(default, skip_serializing_if = "Option::is_none")]
pub instruction_type: Option<String>,
/// Events emitted by this program.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub events: Vec<IdlEvent>,
}

/// Program metadata (lssa-lang compat).
Expand Down Expand Up @@ -191,6 +194,17 @@ pub struct IdlError {
pub msg: Option<String>,
}

/// An event type emitted by a program.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IdlEvent {
/// Event name (matches the struct name).
pub name: String,
/// Program-defined discriminant identifying this event type.
pub discriminant: u32,
/// Fields of the event payload (Borsh-encoded).
pub fields: Vec<IdlArg>,
}

/// Compute the lssa-lang discriminator for an instruction name.
///
/// This is SHA256("global:{name}")[..8], matching lssa-lang's convention.
Expand All @@ -215,6 +229,7 @@ impl SpelIdl {
spec: None,
metadata: None,
instruction_type: None,
events: vec![],
}
}

Expand Down
1 change: 1 addition & 0 deletions spel-framework-core/src/idl_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ fn generate_idl_inner(
spec: None,
metadata: None,
instruction_type: external_instruction,
events: vec![],
})
}

Expand Down
21 changes: 21 additions & 0 deletions spel-framework-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,27 @@ pub fn account_type(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}

/// Mark a struct as an event payload for IDL generation.
///
/// The `discriminant` argument must match the value passed to `emit_event()`.
///
/// # Example
/// ```rust,ignore
/// #[event(discriminant = 1)]
/// pub struct InsufficientFunds {
/// pub requested: u128,
/// pub available: u128,
/// }
/// ```
///
/// This attribute is a no-op at compile time; it is consumed solely by the
/// IDL generator alongside `#[account_type]`.
#[proc_macro_attribute]
pub fn event(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Marker only — detected by generate_idl! and #[lez_program] at compile time.
item
}

/// Generate IDL from a program source file.
///
/// Parses the given Rust source file, finds the `#[lez_program]` module,
Expand Down
3 changes: 2 additions & 1 deletion spel-framework/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! similar to Anchor for Solana.

// Re-export the proc macros
pub use spel_framework_macros::{account_type, generate_idl, instruction, lez_program};
pub use spel_framework_macros::{lez_program, instruction, account_type, generate_idl, event};

// Re-export core types
pub use spel_framework_core::types::{SpelOutput, SpelOutputParts};
Expand All @@ -15,6 +15,7 @@ pub use serde_json;

pub mod prelude {
pub use crate::account_type;
pub use crate::event;
pub use crate::instruction;
pub use crate::lez_program;
pub use borsh::{BorshDeserialize, BorshSerialize};
Expand Down