Lesson content
Custom Errors
#[error_code]
pub enum ErrorCode {
#[msg("Course is not active")]
CourseNotActive,
#[msg("Lesson already completed")]
LessonAlreadyCompleted,
#[msg("Arithmetic overflow")]
Overflow,
}Use errors in constraints: @ ErrorCode::CourseNotActive
Or in handlers: require!(condition, ErrorCode::Overflow)
Events
Events are emitted via transaction logs and indexed off-chain:
#[event]
pub struct LessonCompleted {
pub learner: Pubkey,
pub course: Pubkey,
pub lesson_index: u8,
pub xp_earned: u64,
pub timestamp: i64,
}
// In handler:
emit!(LessonCompleted {
learner: ctx.accounts.learner.key(),
course: ctx.accounts.course.key(),
lesson_index,
xp_earned: course.xp_per_lesson as u64,
timestamp: Clock::get()?.unix_timestamp,
});Client-Side Listening
program.addEventListener("LessonCompleted", (event) => {
console.log("Lesson completed:", event.lessonIndex);
});