You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Event Scanner is a Rust library for monitoring EVM-based smart contract events. It is built on top of the [`alloy`](https://github.com/alloy-rs/alloy) ecosystem and focuses on in-memory scanning without a backing database. Applications provide event filters and callback implementations; the scanner takes care of subscribing to historical ranges, bridging into live mode, and delivering events with retry-aware execution strategies.
11
+
Event Scanner is a Rust library for streaming EVM-based smart contract events. It is built on top of the [`alloy`](https://github.com/alloy-rs/alloy) ecosystem and focuses on in-memory scanning without a backing database. Applications provide event filters; the scanner takes care of fetching historical ranges, bridging into live streaming mode, all whilst delivering the events as streams of data.
12
12
13
13
---
14
14
@@ -29,11 +29,10 @@ Event Scanner is a Rust library for monitoring EVM-based smart contract events.
29
29
30
30
## Features
31
31
32
-
-**Historical replay** – scan block ranges.
33
-
-**Live subscriptions** – stay up to date with latest blocks via WebSocket or IPC transports.
32
+
-**Historical replay** – stream events from past block ranges.
33
+
-**Live subscriptions** – stay up to date with latest events via WebSocket or IPC transports.
34
34
-**Hybrid flow** – automatically transition from historical catch-up into streaming mode.
35
-
-**Composable filters** – register one or many contract + event signature pairs with their own callbacks.
-**Composable filters** – register one or many contract + event signature pairs.
37
36
-**No database** – processing happens in-memory; persistence is left to the host application.
38
37
39
38
---
@@ -42,11 +41,9 @@ Event Scanner is a Rust library for monitoring EVM-based smart contract events.
42
41
43
42
The library exposes two primary layers:
44
43
45
-
-`EventScannerBuilder` / `EventScanner` – the main module the application will interact with.
44
+
-`EventScanner` – the main module the application will interact with.
46
45
-`BlockRangeScanner` – lower-level component that streams block ranges, handles reorg, batching, and provider subscriptions.
47
46
48
-
Callbacks implement the `EventCallback` trait. They are executed through a `CallbackStrategy` that performs retries when necessary before reporting failures.
49
-
50
47
---
51
48
52
49
## Quick Start
@@ -55,38 +52,38 @@ Add `event-scanner` to your `Cargo.toml`:
55
52
56
53
```toml
57
54
[dependencies]
58
-
event-scanner = "0.1.0-alpha.1"
55
+
event-scanner = "0.1.0-alpha.2"
59
56
```
60
-
Create a callback implementing `EventCallback` and register it with the builder:
57
+
58
+
Create an event stream for the given event filters registered with the `EventScanner`:
-`with_callback_strategy(strategy)` – override retry behaviour (`StateSyncAwareStrategy` by default).
104
99
-`with_blocks_read_per_epoch` - how many blocks are read at a time in a single batch (taken into consideration when fetching historical blocks)
105
-
-`with_reorg_rewind_depth` - how many blocks to rewind when a reorg is detected
106
-
-`with_block_confirmations` - how many confirmations to wait for before considering a block final
107
-
108
-
Once configured, connect using either `connect_ws::<Ethereum>(ws_url)` or `connect_ipc::<Ethereum>(path)`. This will `build` the `EventScanner` and allow you to call run to start in various [modes](#scanning-Modes).
100
+
-`with_reorg_rewind_depth` - how many blocks to rewind when a reorg is detected (NOTE ⚠️: still WIP)
101
+
-`with_block_confirmations` - how many confirmations to wait for before considering a block final (NOTE ⚠️: still WIP)
109
102
103
+
Once configured, connect using either `connect_ws::<Ethereum>(ws_url)` or `connect_ipc::<Ethereum>(path)`. This will `connect` the `EventScanner` and allow you to create event streams and start scanning in various [modes](#scanning-Modes).
110
104
111
105
### Defining Event Filters
112
106
113
-
Create an `EventFilter` for each contract/event pair you want to track. The filter bundles the contract address, the event signature (from `SolEvent::SIGNATURE`), and an `Arc<dyn EventCallback + Send + Sync>`.
107
+
Create an `EventFilter` for each contract/event pair you want to track. The filter specifies the contract address where events originated, and the event signature (from `SolEvent::SIGNATURE`).
114
108
115
109
Both `contract_address` and `event` fields are optional, allowing for flexible event tracking.
116
110
117
-
You can construct EventFilters using either the builder pattern (recommended) or direct struct construction:
118
-
119
-
### Builder Pattern (Recommended)
120
-
121
111
```rust
122
112
// Track a specific event from a specific contract
event:None, // Will track all events from this contract
152
-
callback:Arc::new(AllEventsCallback),
153
-
};
154
-
155
-
// Track ALL events from ALL contracts in the block range
156
-
letall_events_filter=EventFilter {
157
-
contract_address:None, // Will track events from all contracts
158
-
event:None, // Will track all event types
159
-
callback:Arc::new(GlobalEventsCallback),
160
-
};
161
-
```
162
-
163
-
Register multiple filters by calling either `with_event_filter` repeatedly or `with_event_filters` once.
164
-
165
-
#### Use Cases for Optional Fields
166
-
167
-
The optional `contract_address` and `event` fields enable several powerful use cases:
127
+
Event filters enable several powerful use cases:
168
128
169
129
-**Track all events from a specific contract**: Set `contract_address` but leave `event` as `None`
170
130
-**Track all events across all contracts**: Set both `contract_address` and `event` as `None`
@@ -173,44 +133,16 @@ The optional `contract_address` and `event` fields enable several powerful use c
173
133
174
134
This flexibility allows you to build sophisticated event monitoring systems that can track events at different granularities depending on your application's needs.
175
135
176
-
177
136
### Scanning Modes
178
137
179
-
-**Live mode** – `start(BlockNumberOrTag::Latest, None)` subscribes to new blocks only.
180
-
-**Historical mode** – `start(BlockNumberOrTag::Number(start, Some(BlockNumberOrTag::Number(end)))`, scanner fetches events from a historical block range.
181
-
-**Historical → Live** – `start(BlockNumberOrTag::Number(start, None)` replays from `start` to current head, then streams future blocks.
138
+
-**Live mode** – `start_scanner(BlockNumberOrTag::Latest, None)` subscribes to new blocks only.
139
+
-**Historical mode** – `start_scanner(BlockNumberOrTag::Number(start), Some(BlockNumberOrTag::Number(end)))`, scanner fetches events from a historical block range.
140
+
-**Historical → Live** – `start_scanner(BlockNumberOrTag::Number(start), None)` replays from `start` to current head, then streams future blocks.
182
141
183
142
For now modes are deduced from the `start` and `end` parameters. In the future, we might add explicit commands to select the mode.
184
143
185
144
See the integration tests under `tests/live_mode`, `tests/historic_mode`, and `tests/historic_to_live` for concrete examples.
Advanced users can write custom retry behaviour by implementing the `CallbackStrategy` trait. The default `StateSyncAwareStrategy` automatically detects state-sync errors and performs exponential backoff ([smart retry mechanism](https://github.com/taikoxyz/taiko-mono/blob/f4b3a0e830e42e2fee54829326389709dd422098/packages/taiko-client/pkg/chain_iterator/block_batch_iterator.go#L149) from the geth driver) before falling back to a fixed retry policy configured via `FixedRetryConfig`.
202
-
203
-
```rust
204
-
#[async_trait]
205
-
pubtraitCallbackStrategy:Send+Sync {
206
-
asyncfnexecute(
207
-
&self,
208
-
callback:&Arc<dynEventCallback+Send+Sync>,
209
-
log:&Log,
210
-
) ->anyhow::Result<()>;
211
-
}
212
-
```
213
-
214
146
---
215
147
216
148
## Examples
@@ -226,7 +158,7 @@ RUST_LOG=info cargo run -p simple_counter
226
158
RUST_LOG=info cargo run -p historical_scanning
227
159
```
228
160
229
-
Both examples spin up a local `anvil` instance and deploy a demo counter contract before starting the scanner.
161
+
Both examples spin up a local `anvil` instance, deploy a demo counter contract, and demonstrate using event streams to process events.
0 commit comments