miden_client/rpc/domain/
note.rs1use alloc::vec::Vec;
2
3use miden_objects::{
4 block::BlockHeader,
5 crypto::merkle::MerklePath,
6 note::{Note, NoteExecutionHint, NoteId, NoteInclusionProof, NoteMetadata, NoteTag, NoteType},
7 Digest, Felt,
8};
9
10use super::{MissingFieldHelper, RpcConversionError};
11use crate::rpc::{
12 generated::{note::NoteMetadata as ProtoNoteMetadata, responses::SyncNoteResponse},
13 RpcError,
14};
15
16impl TryFrom<ProtoNoteMetadata> for NoteMetadata {
17 type Error = RpcConversionError;
18
19 fn try_from(value: ProtoNoteMetadata) -> Result<Self, Self::Error> {
20 let sender = value
21 .sender
22 .ok_or_else(|| ProtoNoteMetadata::missing_field("Sender"))?
23 .try_into()?;
24 let note_type = NoteType::try_from(value.note_type as u64)?;
25 let tag = NoteTag::from(value.tag);
26 let execution_hint_tag = (value.execution_hint & 0xff) as u8;
27 let execution_hint_payload = ((value.execution_hint >> 8) & 0xffffff) as u32;
28 let execution_hint =
29 NoteExecutionHint::from_parts(execution_hint_tag, execution_hint_payload)?;
30
31 let aux = Felt::try_from(value.aux).map_err(|_| RpcConversionError::NotAValidFelt)?;
32
33 Ok(NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?)
34 }
35}
36
37impl From<NoteMetadata> for ProtoNoteMetadata {
38 fn from(value: NoteMetadata) -> Self {
39 ProtoNoteMetadata {
40 sender: Some(value.sender().into()),
41 note_type: value.note_type() as u32,
42 tag: value.tag().into(),
43 execution_hint: value.execution_hint().into(),
44 aux: value.aux().into(),
45 }
46 }
47}
48
49#[derive(Debug)]
54pub struct NoteSyncInfo {
55 pub chain_tip: u32,
57 pub block_header: BlockHeader,
59 pub mmr_path: MerklePath,
66 pub notes: Vec<CommittedNote>,
68}
69
70impl TryFrom<SyncNoteResponse> for NoteSyncInfo {
71 type Error = RpcError;
72
73 fn try_from(value: SyncNoteResponse) -> Result<Self, Self::Error> {
74 let chain_tip = value.chain_tip;
75
76 let block_header = value
78 .block_header
79 .ok_or(RpcError::ExpectedDataMissing("BlockHeader".into()))?
80 .try_into()?;
81
82 let mmr_path = value
83 .mmr_path
84 .ok_or(RpcError::ExpectedDataMissing("MmrPath".into()))?
85 .try_into()?;
86
87 let mut notes = vec![];
89 for note in value.notes {
90 let note_id: Digest = note
91 .note_id
92 .ok_or(RpcError::ExpectedDataMissing("Notes.Id".into()))?
93 .try_into()?;
94
95 let note_id: NoteId = note_id.into();
96
97 let merkle_path = note
98 .merkle_path
99 .ok_or(RpcError::ExpectedDataMissing("Notes.MerklePath".into()))?
100 .try_into()?;
101
102 let metadata = note
103 .metadata
104 .ok_or(RpcError::ExpectedDataMissing("Metadata".into()))?
105 .try_into()?;
106
107 let committed_note =
108 CommittedNote::new(note_id, note.note_index as u16, merkle_path, metadata);
109
110 notes.push(committed_note);
111 }
112
113 Ok(NoteSyncInfo { chain_tip, block_header, mmr_path, notes })
114 }
115}
116
117#[derive(Debug, Clone)]
122pub struct CommittedNote {
123 note_id: NoteId,
125 note_index: u16,
127 merkle_path: MerklePath,
129 metadata: NoteMetadata,
131}
132
133impl CommittedNote {
134 pub fn new(
135 note_id: NoteId,
136 note_index: u16,
137 merkle_path: MerklePath,
138 metadata: NoteMetadata,
139 ) -> Self {
140 Self {
141 note_id,
142 note_index,
143 merkle_path,
144 metadata,
145 }
146 }
147
148 pub fn note_id(&self) -> &NoteId {
149 &self.note_id
150 }
151
152 pub fn note_index(&self) -> u16 {
153 self.note_index
154 }
155
156 pub fn merkle_path(&self) -> &MerklePath {
157 &self.merkle_path
158 }
159
160 pub fn metadata(&self) -> NoteMetadata {
161 self.metadata
162 }
163}
164
165#[allow(clippy::large_enum_variant)]
170pub enum NetworkNote {
171 Private(NoteId, NoteMetadata, NoteInclusionProof),
174 Public(Note, NoteInclusionProof),
176}
177
178impl NetworkNote {
179 pub fn inclusion_proof(&self) -> &NoteInclusionProof {
181 match self {
182 NetworkNote::Private(_, _, inclusion_proof) => inclusion_proof,
183 NetworkNote::Public(_, inclusion_proof) => inclusion_proof,
184 }
185 }
186
187 pub fn metadata(&self) -> &NoteMetadata {
189 match self {
190 NetworkNote::Private(_, metadata, _) => metadata,
191 NetworkNote::Public(note, _) => note.metadata(),
192 }
193 }
194
195 pub fn id(&self) -> NoteId {
197 match self {
198 NetworkNote::Private(id, ..) => *id,
199 NetworkNote::Public(note, _) => note.id(),
200 }
201 }
202}