Skip to main content

Module cpi_event

Module cpi_event 

Source
Expand description

Self-CPI event emission primitives.

Log output is lossy. Transaction metadata is not. A program that needs events to arrive at indexers regardless of log truncation invokes itself with a distinctive CPI whose bytes carry the event payload. This module provides the building blocks: a reserved discriminator so the dispatcher can route the CPI to a no-op sentinel, a wire-format helper for the instruction data, and a one-line pattern programs can copy.

§Wire format

[0..2]   CPI_EVENT_MARKER   (0xE0, 0x1E)
[2]      event tag          (the byte from `#[hopper::event(tag = N)]`)
[3..]    event payload      (from `HopperEvent::as_bytes()`)

The two-byte marker is the reserved Hopper discriminator for self-CPI events and is unlikely to collide with any sensibly chosen user discriminator. The user-facing instruction declaration for the sentinel is:

#[instruction(discriminator = [0xE0, 0x1E])]
fn __hopper_event_sink(_ctx: &mut Context<'_>) -> ProgramResult {
    Ok(())
}

§Why this pattern works

Anchor’s emit_cpi! uses the same trick: a self-CPI carrying payload bytes guarantees the event appears in the transaction’s inner-instruction list, which RPC nodes do not truncate. Indexers scan for the reserved marker and decode the tail as the event.

Hopper’s version is leaner: a two-byte marker plus a one-byte event tag gives the indexer everything it needs to route without the Anchor eight-byte discriminator overhead.

Constants§

CPI_EVENT_MARKER
The reserved self-CPI event discriminator.
EVENT_AUTHORITY_SEED
Canonical PDA seed for the Hopper event-authority. Match this in the program’s sentinel handler setup so the CPI signer resolves.

Functions§

encode_event_cpi
Fill an out buffer with the CPI wire format for an event.
invoke_event_cpi
Invoke a self-CPI carrying the encoded event payload.