Context
Intent::is_expired(now) and UniswapXDecoder::fetch_open_intents both filter by deadline > now, but there is no structured monitor that keeps a live feed of open intents, prunes expired ones, and exposes metrics (count, cross-chain %, protocol breakdown). src/monitor/mod.rs is a stub. Filling it in with a simple in-memory intent pool and a tick-based pruner is a clean starter for someone who wants to learn the codebase.
Scope
- Implement
IntentPool in src/monitor/mod.rs:
pub struct IntentPool { intents: RwLock<HashMap<String, Intent>>, ... }.
pub fn add(&self, intent: Intent) — de-dupe by intent.id.
pub fn prune_expired(&self, now: u64) -> usize — returns number pruned.
pub fn len(&self), is_empty().
pub fn by_protocol(&self, protocol: &Protocol) -> Vec<Intent>.
pub fn by_dest_chain(&self, chain: Chain) -> Vec<Intent>.
- Unit tests for every method — add 5+ synthetic intents, assert pruning + filters behave.
- In
src/main.rs (or whatever entry point exists), wire IntentPool into the solver loop so fetch_open_intents from all decoders feeds into a single pool.
Acceptance criteria
cargo test monitor green.
cargo clippy -- -D warnings clean.
IntentPool is Send + Sync and safe to share across solver tasks.
- The public API has rustdoc.
Reference: src/intents/types.rs::Intent::is_expired for the expiry rule; PR #3 for the Across decoder pattern being wired into the same pool.
Estimated effort
S (3–5 hours)
— kcolbchain / Abhishek Krishna
Context
Intent::is_expired(now)andUniswapXDecoder::fetch_open_intentsboth filter bydeadline > now, but there is no structured monitor that keeps a live feed of open intents, prunes expired ones, and exposes metrics (count, cross-chain %, protocol breakdown).src/monitor/mod.rsis a stub. Filling it in with a simple in-memory intent pool and a tick-based pruner is a clean starter for someone who wants to learn the codebase.Scope
IntentPoolinsrc/monitor/mod.rs:pub struct IntentPool { intents: RwLock<HashMap<String, Intent>>, ... }.pub fn add(&self, intent: Intent)— de-dupe byintent.id.pub fn prune_expired(&self, now: u64) -> usize— returns number pruned.pub fn len(&self),is_empty().pub fn by_protocol(&self, protocol: &Protocol) -> Vec<Intent>.pub fn by_dest_chain(&self, chain: Chain) -> Vec<Intent>.src/main.rs(or whatever entry point exists), wireIntentPoolinto the solver loop sofetch_open_intentsfrom all decoders feeds into a single pool.Acceptance criteria
cargo test monitorgreen.cargo clippy -- -D warningsclean.IntentPoolisSend + Syncand safe to share across solver tasks.Reference:
src/intents/types.rs::Intent::is_expiredfor the expiry rule; PR #3 for the Across decoder pattern being wired into the same pool.Estimated effort
S (3–5 hours)
— kcolbchain / Abhishek Krishna