use alloc::sync::Arc;
use miden_protocol::account::AccountId;
use miden_protocol::block::BlockNumber;
use crate::ClientError;
use crate::store::{InputNoteCursor, InputNoteRecord, NoteFilter, Store};
pub struct InputNoteReader {
store: Arc<dyn Store>,
consumer: AccountId,
block_range: Option<(BlockNumber, BlockNumber)>,
cursor: Option<InputNoteCursor>,
}
impl InputNoteReader {
pub fn new(store: Arc<dyn Store>, consumer: AccountId) -> Self {
Self {
store,
consumer,
block_range: None,
cursor: None,
}
}
#[must_use]
pub fn in_block_range(mut self, from: BlockNumber, to: BlockNumber) -> Self {
self.block_range = Some((from, to));
self
}
pub fn reset(&mut self) {
self.cursor = None;
}
pub async fn next(&mut self) -> Result<Option<InputNoteRecord>, ClientError> {
let (block_start, block_end) = match self.block_range {
Some((from, to)) => (Some(from), Some(to)),
None => (None, None),
};
let note = self
.store
.get_input_note_after(
NoteFilter::Consumed,
self.consumer,
block_start,
block_end,
self.cursor,
)
.await
.map_err(ClientError::StoreError)?;
if let Some(note) = ¬e {
let cursor = InputNoteCursor::from_record(note).ok_or_else(|| {
ClientError::MissingNoteConsumptionPosition(note.details_commitment().as_word())
})?;
self.cursor = Some(cursor);
}
Ok(note)
}
}