miden_client/rpc/domain/
note.rs1use alloc::vec::Vec;
2
3use miden_objects::{
4 Digest, Felt,
5 block::BlockHeader,
6 crypto::merkle::MerklePath,
7 note::{Note, NoteExecutionHint, NoteId, NoteInclusionProof, NoteMetadata, NoteTag, NoteType},
8};
9
10use super::{MissingFieldHelper, RpcConversionError};
11use crate::rpc::{
12 RpcError,
13 generated::{note::NoteMetadata as ProtoNoteMetadata, responses::SyncNoteResponse},
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(u64::from(value.note_type))?;
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) & 0x00ff_ffff) 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 = CommittedNote::new(
108 note_id,
109 u16::try_from(note.note_index).expect("note index out of range"),
110 merkle_path,
111 metadata,
112 );
113
114 notes.push(committed_note);
115 }
116
117 Ok(NoteSyncInfo { chain_tip, block_header, mmr_path, notes })
118 }
119}
120
121#[derive(Debug, Clone)]
126pub struct CommittedNote {
127 note_id: NoteId,
129 note_index: u16,
131 merkle_path: MerklePath,
133 metadata: NoteMetadata,
135}
136
137impl CommittedNote {
138 pub fn new(
139 note_id: NoteId,
140 note_index: u16,
141 merkle_path: MerklePath,
142 metadata: NoteMetadata,
143 ) -> Self {
144 Self {
145 note_id,
146 note_index,
147 merkle_path,
148 metadata,
149 }
150 }
151
152 pub fn note_id(&self) -> &NoteId {
153 &self.note_id
154 }
155
156 pub fn note_index(&self) -> u16 {
157 self.note_index
158 }
159
160 pub fn merkle_path(&self) -> &MerklePath {
161 &self.merkle_path
162 }
163
164 pub fn metadata(&self) -> NoteMetadata {
165 self.metadata
166 }
167}
168
169#[allow(clippy::large_enum_variant)]
174pub enum NetworkNote {
175 Private(NoteId, NoteMetadata, NoteInclusionProof),
178 Public(Note, NoteInclusionProof),
180}
181
182impl NetworkNote {
183 pub fn inclusion_proof(&self) -> &NoteInclusionProof {
185 match self {
186 NetworkNote::Private(_, _, inclusion_proof)
187 | NetworkNote::Public(_, inclusion_proof) => inclusion_proof,
188 }
189 }
190
191 pub fn metadata(&self) -> &NoteMetadata {
193 match self {
194 NetworkNote::Private(_, metadata, _) => metadata,
195 NetworkNote::Public(note, _) => note.metadata(),
196 }
197 }
198
199 pub fn id(&self) -> NoteId {
201 match self {
202 NetworkNote::Private(id, ..) => *id,
203 NetworkNote::Public(note, _) => note.id(),
204 }
205 }
206}