miden_client/sync/note_observer.rs
1//! Side-effect-only observer trait for per-note arrivals during sync.
2
3use alloc::boxed::Box;
4
5use async_trait::async_trait;
6use miden_protocol::note::NoteAttachments;
7
8use crate::ClientError;
9use crate::rpc::domain::note::CommittedNote;
10use crate::sync::StateSyncUpdate;
11
12/// Per-note + post-sync side-channel into [`crate::sync::StateSync`].
13/// Attach via `StateSync::with_note_observer(...)`. Multiple observers
14/// run independently; errors are logged, never abort sync.
15#[async_trait(?Send)]
16pub trait NoteObserver {
17 /// Identifier surfaced on `tracing::warn!` events for this observer.
18 fn name(&self) -> &'static str;
19
20 /// Per-note hook. Runs before the screener verdict. `attachments` is the note's resolved
21 /// attachment content for this sync window (`None` if absent).
22 ///
23 /// Returns `true` to mark the enclosing block as relevant even if the screener discards it,
24 /// so sync persists its header.
25 async fn observe(
26 &self,
27 committed_note: &CommittedNote,
28 attachments: Option<&NoteAttachments>,
29 ) -> Result<bool, ClientError>;
30
31 /// Post-sync hook, invoked once after the sync window closes.
32 /// Default impl is a no-op for observers that only need `observe()`.
33 async fn apply(&self, _sync_update: &StateSyncUpdate) -> Result<(), ClientError> {
34 Ok(())
35 }
36}