Events allow your program to emit structured data that clients can subscribe to and monitor. Anchor provides two ways to emit events: through program logs withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
Use this file to discover all available pages before exploring further.
emit! or through Cross Program Invocations with emit_cpi!.
Defining Events
Define events using the#[event] attribute on a struct:
AnchorSerialize and AnchorDeserialize.
Emitting Events with emit!
Theemit! macro is the simpler approach, writing events to program logs using the sol_log_data() syscall:
How emit! Works
- Serializes the event data
- Calls
sol_log_data()to write to program logs - Encodes data as base64 with the prefix
Program data:
Program Logs Output
When an event is emitted, it appears in the logs:Emitting Events with emit_cpi!
Theemit_cpi! macro emits events through a Cross Program Invocation, including the data in the instruction data instead of logs. This approach is more reliable when working with data providers that might truncate logs.
Setup
Enable theevent-cpi feature in Cargo.toml:
Usage
#[event_cpi] attribute must be added to the accounts struct. It automatically includes additional accounts required for the self-CPI.
Subscribing to Events in TypeScript
Using emit! Events
Listen to events withaddEventListener():
Using emit_cpi! Events
For CPI events, fetch the transaction and decode manually:Complete Example
Here’s a real-world example from a token staking program:emit! vs emit_cpi!
| Feature | emit! | emit_cpi! |
|---|---|---|
| Complexity | Simple | Requires feature flag |
| Performance | Low compute cost | Higher compute cost (CPI) |
| Reliability | May be truncated | More reliable |
| Setup | No special setup | Needs #[event_cpi] attribute |
| Subscription | addEventListener() | Manual decoding |
| Best for | Most use cases | High-value events |
Best Practices
- Keep events small: Only include necessary data to minimize compute costs
- Add timestamps: Always include a timestamp for event ordering
- Use descriptive names: Name events clearly (e.g.,
TokensMinted,UserRegistered) - Version events: Consider adding a version field for future compatibility
- Test event emission: Write tests to verify events are emitted correctly
- Document events: Explain when each event is emitted and what data it contains
Limitations
- Log truncation: RPC providers may truncate program logs (use
emit_cpi!for critical events) - No event history: Events are only available in transaction logs, not stored on-chain
- Size limits: Very large events may hit transaction size limits