graph_native/lib.rs
1//! graph-native: Runtime types for native subgraph handler execution.
2//!
3//! This crate provides the types that generated Rust handler code depends on.
4//! It mirrors the graph-ts host function interface but as direct Rust calls,
5//! eliminating the WASM serialization boundary.
6//!
7//! ## Plugin interface
8//!
9//! A native subgraph plugin is a compiled `.so` that implements [`NativeHandlers`].
10//! Graph-node loads the plugin, calls `supported_handlers()` to discover which
11//! handlers have native implementations, and routes matching triggers to
12//! `handle_trigger()` instead of the WASM path.
13//!
14//! Handlers not in the supported list fall back to WASM execution.
15
16mod abi;
17mod contract;
18mod entity;
19mod helpers;
20mod log;
21mod types;
22
23use anyhow::Error;
24use std::future::Future;
25use std::pin::Pin;
26
27/// The trait that a native subgraph plugin must implement.
28///
29/// Generated by the native-transpiler's `lib.ts` codegen. The `.so` plugin
30/// exports a constructor function that returns a `Box<dyn NativeHandlers>`.
31///
32/// Phase C will add plugin loading in graph-node's RuntimeHost that:
33/// 1. dlopen's the .so
34/// 2. Calls the constructor to get a NativeHandlers instance
35/// 3. Routes triggers to handle_trigger() for supported handlers
36pub trait NativeHandlers: Send + Sync {
37 /// Returns the list of handler names this plugin supports natively.
38 /// Example: vec!["handleTransfer", "handleApproval"]
39 /// Handlers not in this list fall back to WASM execution.
40 fn supported_handlers(&self) -> Vec<String>;
41
42 /// Execute a handler for a matched trigger.
43 ///
44 /// - `handler_name`: the handler to invoke (must be in supported_handlers)
45 /// - `log`: the decoded Ethereum log event (trigger data)
46 /// - `ctx`: handler context wrapping BlockState for entity operations
47 ///
48 /// The handler reads event data from `log`, creates/updates/removes
49 /// entities through `ctx`, and returns Ok(()) on success.
50 ///
51 /// Note: This takes &Log (our trigger struct) for now. Phase C will
52 /// change this to accept graph-node's MappingTrigger directly.
53 fn handle_trigger<'a>(
54 &'a self,
55 handler_name: &str,
56 log: &'a crate::log::Log,
57 ctx: &'a mut dyn crate::entity::HandlerContext,
58 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>;
59}
60
61pub mod prelude {
62 pub use crate::abi::decode_event_params;
63 pub use crate::contract::Contract;
64 pub use crate::entity::{
65 bytes_to_hex_id, bytes_to_value, hex_id_to_bytes, read_bigdecimal, read_bigint, read_bool,
66 read_bytes, read_i32, read_string, read_value, Entity, EntityCache, EntityIdValue,
67 DataSourceContext, HandlerContext, IntoEntityValue, Value,
68 };
69 pub use crate::helpers::*;
70 pub use crate::{debug, error, info, warning};
71 pub use crate::log::Log;
72 pub use crate::types::*;
73 pub use crate::NativeHandlers;
74 pub use anyhow;
75}