Thanks for your interest in contributing! This guide explains how to set up your environment, make changes, run checks locally, and submit high‑quality pull requests that pass CI.
event-scanner is a Rust library for monitoring and streaming EVM-based smart contract events. It is built on the alloy ecosystem and provides in-memory scanning. See README.md for features, usage, examples, and testing notes.
- Manifest:
Cargo.toml - Library code:
src/ - Examples:
examples/live_scanning,examples/historical_scanningetc. - Integration tests:
tests/ - Formatting:
rustfmt.toml - Toolchain pin:
rust-toolchain.toml - CI:
.github/workflows/check.ymland.github/workflows/test.yml
- Rust toolchains via
rustup- Minimum supported Rust version (MSRV): 1.89 (see
rust-toolchain.toml) - Formatting uses nightly
rustfmtin CI
- Minimum supported Rust version (MSRV): 1.89 (see
- Recommended tooling
cargo-nextestfor fast, reliable test runs:cargo install cargo-nextesttyposfor spell checking:cargo install typos-cli(orbrew install typos)- A recent
rust-analyzerfor IDE support
- Runtime/dev tools
- For examples and some tests, you'll need an Ethereum dev node such as Foundry's anvil
- The repository is exercised against anvil; if you encounter issues on other nodes/providers, please report them at https://github.com/OpenZeppelin/Event-Scanner/issues
src/– core libraryexamples/– runnable examples that deploy a demo contract and scan eventstests/– integration tests covering live, historical and hybrid flows.github/workflows/– CI configuration (build, fmt, clippy, typos, tests)
- Fork the repository and clone your fork.
- Ensure toolchains are installed:
rustup toolchain install 1.89(MSRV)rustup toolchain install nightly(for rustfmt parity with CI)
- Optional helpers:
cargo install cargo-nextestcargo install typos-cli
Build the crate:
cargo build --locked --all-targets --all-featuresRun the test suite (we recommend nextest):
cargo nextest run --features test-utils
# or
cargo test --features test-utilsRun examples:
RUST_LOG=info cargo run --example live_scanningu --features example
# or
RUST_LOG=info cargo run --example historical_scanning --features exampleLogging / observability notes:
- The library's internal logs are compile-time opt-in via the
tracingfeature. - If the feature is disabled, internal logging calls compile to no-ops.
- Examples install a
tracing_subscriberand read filters fromRUST_LOG.
When running an example with internal logging, simply enable the example feature:
RUST_LOG=event_scanner=debug cargo run --example historical_scanning --features exampleYou can also combine filters to keep other dependencies quiet:
RUST_LOG=warn,event_scanner=info cargo run --example historical_scanning --features exampleNote: Examples start a local anvil instance and deploy a demo contract. If you run into issues when using a different node/provider, please report them at https://github.com/OpenZeppelin/Event-Scanner/issues.
- Formatting is enforced by
rustfmtwith the settings inrustfmt.toml.- CI runs formatting on nightly. To match CI locally:
cargo +nightly fmt --all --check
- To apply formatting locally:
cargo +nightly fmt --all
- CI runs formatting on nightly. To match CI locally:
- Linting is enforced with
clippyand pedantic lints are denied.- To check locally (matches CI):
cargo clippy --all-targets --all-features -- -D warnings -D clippy::pedantic
- To apply automatic fixes where possible:
cargo clippy --all-targets --all-features --fix --allow-dirty --allow-staged -- -D warnings -D clippy::pedantic
- To check locally (matches CI):
- Spelling/typos:
- CI uses
typos. Locally:typos
- CI uses
Before opening a PR, please ensure the following commands succeed locally:
# Build (all targets & features)
cargo build --locked --all-targets --all-features
# Format (nightly to match CI)
cargo +nightly fmt --all --check
# Lint (deny warnings, pedantic)
cargo clippy --all-targets --all-features -- -D warnings -D clippy::pedantic
# Spelling
typos
# Tests (prefer nextest)
cargo nextest run --features test-utils- Branch from
mainwith a descriptive name, e.g.feat/reorg-handling,fix/rpc-retries,docs/contributing. - Keep PRs focused and reasonably small; large changes are harder to review.
- Write clear commit messages that explain the why and the what. Conventional Commits are welcome but not required.
- Include tests for new functionality or bug fixes where applicable.
- Update documentation and examples as needed.
- Ensure CI passes. Required checks include:
- Build: cargo build
- Format: rustfmt (nightly)
- Lint: clippy (pedantic, warnings denied)
- Typos: typos
- Tests: see
.github/workflows/test.yml
- CODEOWNERS: reviewers may be auto-assigned based on
CODEOWNERS.
PR description template (suggested):
## Summary
Short summary of the change and context.
## Motivation
Why is this change needed?
## Approach
Key implementation details, trade-offs, and alternatives considered.
## Checklist
- [ ] Builds locally with `--all-targets --all-features`
- [ ] `cargo +nightly fmt --all --check`
- [ ] `cargo clippy --all-targets --all-features -- -D warnings -D clippy::pedantic`
- [ ] `typos`
- [ ] Tests pass (`cargo nextest run --features test-utils`)
- [ ] Docs/README/examples updated (if applicable)- Integration tests live under
tests/and cover live, historical, and hybrid flows. - Prefer
cargo-nextestfor speed and improved output. - Where practical, add regression tests when fixing bugs.
Benchmark dumps are pre-generated Anvil state files with events, stored in benches/dumps/. They allow benchmarks to run without regenerating events each time.
To generate new dumps run the generator:
cargo run --release --bin generate_dump --features bench-utils -- \
--events 100000 \
--output benches/dumps/state_100000.jsonNote: The --features bench-utils flag is required to enable the dependencies needed by the generator.
This creates:
benches/dumps/state_100000.json.gz(compressed state dump)benches/dumps/state_100000.metadata.json(metadata)
Afterwards, if necessary, commit the generated .json.gz and .metadata.json files to the repository.
- High-level architecture and core traits/components are described in
README.md. - For non-trivial changes (new abstractions, public API changes), please open an issue first to discuss design direction before implementation.
- Use GitHub Issues for bug reports and feature requests.
- Include reproduction steps, expected vs actual behavior, logs, and environment details.
- Security-related reports: please follow
SECURITY.md.
- Public crates follow semver. Breaking changes to the public API should be noted clearly in PRs and release notes.
- New features and fixes may be released in pre-releases before a stable cut.
- Be respectful and constructive.
- Prefer clear, actionable feedback.
- Assume good intent and collaborate to reach the best solution.
Thanks again for contributing to Event Scanner!