pub trait Plugin:
Send
+ Sync
+ 'static {
// Required method
fn name(&self) -> &'static str;
// Provided methods
fn on_load<'a>(&'a self) -> PluginFuture<'a> { ... }
fn on_raw<'a>(&'a self, _slot: u64, _raw: &'a Value) -> PluginFuture<'a> { ... }
fn on_block<'a>(&'a self, _block: &'a BlockData) -> PluginFuture<'a> { ... }
fn on_transaction<'a>(
&'a self,
_tx: &'a TransactionData,
) -> PluginFuture<'a> { ... }
fn on_token_transfer<'a>(
&'a self,
_transfer: &'a TokenTransferData,
) -> PluginFuture<'a> { ... }
fn on_account_activity<'a>(
&'a self,
_activity: &'a AccountActivityData,
) -> PluginFuture<'a> { ... }
fn on_skipped_slot<'a>(&'a self, _slot: u64) -> PluginFuture<'a> { ... }
fn on_exit<'a>(&'a self) -> PluginFuture<'a> { ... }
}Expand description
Observe Solana block and transaction events.
Two approaches to consuming data:
1. Custom extraction — implement on_raw and parse the raw
JSON-RPC response yourself. Use extract_block()
as an optional utility.
2. Built-in extraction — implement on_block,
on_transaction, etc. The framework extracts structured data
and calls your hooks.
Both can be combined: on_raw fires first with the raw JSON, then the framework
extracts and calls the structured hooks.
§Example: Custom extraction
use quicknode_cascade::solana::{Plugin, PluginFuture};
struct RawProcessor;
impl Plugin for RawProcessor {
fn name(&self) -> &'static str { "raw" }
fn on_raw<'a>(&'a self, slot: u64, raw: &'a serde_json::Value) -> PluginFuture<'a> {
Box::pin(async move {
let txs = raw.get("transactions").and_then(|v| v.as_array());
println!("slot {} has {} txs", slot, txs.map_or(0, |t| t.len()));
Ok(())
})
}
}§Example: Built-in extraction
use quicknode_cascade::solana::{Plugin, PluginFuture, BlockData, TransactionData};
struct MyIndexer;
impl Plugin for MyIndexer {
fn name(&self) -> &'static str { "my-indexer" }
fn on_block<'a>(&'a self, block: &'a BlockData) -> PluginFuture<'a> {
Box::pin(async move {
println!("slot {} — {} txs", block.slot, block.transaction_count);
Ok(())
})
}
fn on_transaction<'a>(&'a self, tx: &'a TransactionData) -> PluginFuture<'a> {
Box::pin(async move {
if !tx.is_vote {
println!(" tx {}", tx.signature);
}
Ok(())
})
}
}Required Methods§
Provided Methods§
Sourcefn on_load<'a>(&'a self) -> PluginFuture<'a>
fn on_load<'a>(&'a self) -> PluginFuture<'a>
Called once when the runner starts, before any data is fetched. Use this to create tables, open connections, or validate config.
Sourcefn on_raw<'a>(&'a self, _slot: u64, _raw: &'a Value) -> PluginFuture<'a>
fn on_raw<'a>(&'a self, _slot: u64, _raw: &'a Value) -> PluginFuture<'a>
Called for every non-skipped slot with the full raw JSON-RPC response.
This fires BEFORE the built-in extraction hooks (on_block, on_transaction, etc.).
Use this for custom extraction — parse the JSON however you need.
The name on_raw is consistent across all chain modules so multi-chain
code follows the same pattern everywhere.
If you also want the framework’s structured data from within your custom
extraction, call extract_block() on a clone of the JSON.
Sourcefn on_block<'a>(&'a self, _block: &'a BlockData) -> PluginFuture<'a>
fn on_block<'a>(&'a self, _block: &'a BlockData) -> PluginFuture<'a>
Called for each block. Fired once per slot, before transactions.
Sourcefn on_transaction<'a>(&'a self, _tx: &'a TransactionData) -> PluginFuture<'a>
fn on_transaction<'a>(&'a self, _tx: &'a TransactionData) -> PluginFuture<'a>
Called for each transaction within a block.
Fired in order of tx_index within the slot.
Sourcefn on_token_transfer<'a>(
&'a self,
_transfer: &'a TokenTransferData,
) -> PluginFuture<'a>
fn on_token_transfer<'a>( &'a self, _transfer: &'a TokenTransferData, ) -> PluginFuture<'a>
Called for each token balance change within a transaction. Only fired when the balance actually changed (pre != post).
Sourcefn on_account_activity<'a>(
&'a self,
_activity: &'a AccountActivityData,
) -> PluginFuture<'a>
fn on_account_activity<'a>( &'a self, _activity: &'a AccountActivityData, ) -> PluginFuture<'a>
Called for each account touched by a transaction (SOL balance changes).
Sourcefn on_skipped_slot<'a>(&'a self, _slot: u64) -> PluginFuture<'a>
fn on_skipped_slot<'a>(&'a self, _slot: u64) -> PluginFuture<'a>
Called when a slot was skipped by the Solana leader (no block produced).
Sourcefn on_exit<'a>(&'a self) -> PluginFuture<'a>
fn on_exit<'a>(&'a self) -> PluginFuture<'a>
Called once when the runner is shutting down. Flush buffers, close connections.