Skip to content

Latest commit

 

History

History
160 lines (99 loc) · 2.54 KB

06_events.md

File metadata and controls

160 lines (99 loc) · 2.54 KB

🛹 Events and Communication


tl; dr


  • Events in Anchor provide a mechanism for notifying and communicating between different components of a Solana dApp.

  • Events are structured pieces of data holding information about a specific occurrence in a program.

  • Since there is no native support for events in Solana, Anchor events depend on logging to emit events.

    • Programs log base64 encoded event data and clients parse the logs of the transaction to interpret the events.


Defining Events


  • Events are defined using #[event] attribute macro, which allows the specification of fields that an event should contain:

#[event]
pub struct TransferEvent {
    from: Pubkey,
    to: Pubkey,
    amount: u64,
}


Emitting Events


  • To emit an event, you can use the emit! macro:

emit!(TransferEvent {
    from: *ctx.accounts.from.key,
    to: *ctx.accounts.to.key,
    amount,
});


Subscribing to Events


  • Anyone can subscribe to events emitted by your program, through the @coral-xyz/anchor library:

const subscriptionId = program.addEventListener("TransferEvent", (event) => {
  // Handle event...
});

  • The event listener should be removed once it's no longer needed:

program.removeEventListener(subscriptionId);


CPI Events


  • Solana nodes truncate logs larger than 10KB, which makes regular events emitted via emit! unreliable.

  • Unlike logs, RPC providers store instruction data without truncation.

    • CPI events make use of this by executing a self-invoke with the event data to store the event(s) in the instruction.
  • To use CPI events, you can enable event-cpi:


anchor-lang = { version = "0.29.0", features = ["event-cpi"] }

  • Then, add #[event_cpi] to accounts struct:

#[event_cpi]
#[derive(Accounts)]
pub struct TransferContext {}

  • And the instruction handler:

#![allow(unused)]
fn main() {
#[program]
pub mod my_program {
    use super::*;

    pub fn transfer(ctx: Context<TransferContext>, amount: u64) -> Result<()>  {
        // Perform transfer logic

        // Emit the TransferEvent
        emit_cpi!(TransferEvent {
            from: *ctx.accounts.from.key,
            to: *ctx.accounts.to.key,
            amount,
        });

        Ok(())
    }
}
}


Resources