Skip to main content

miden_standards/note/
network_note.rs

1use miden_protocol::account::AccountId;
2use miden_protocol::note::{Note, NoteAttachment, NoteMetadata, NoteType};
3
4use crate::note::{NetworkAccountTarget, NetworkAccountTargetError, NoteExecutionHint};
5
6/// A wrapper around a [`Note`] that is guaranteed to target a network account via a
7/// [`NetworkAccountTarget`] attachment.
8///
9/// This represents a note that is specifically targeted at a single network account. In the future,
10/// other types of network notes may exist (e.g., SWAP notes that can be consumed by network
11/// accounts but are not targeted at a specific one).
12#[derive(Clone, Debug, PartialEq, Eq)]
13pub struct AccountTargetNetworkNote {
14    note: Note,
15}
16
17impl AccountTargetNetworkNote {
18    /// Attempts to construct an [`AccountTargetNetworkNote`] from `note`.
19    ///
20    /// Returns an error if:
21    /// - the note is not [`NoteType::Public`].
22    /// - the note's attachment cannot be decoded as a [`NetworkAccountTarget`].
23    pub fn new(note: Note) -> Result<Self, NetworkAccountTargetError> {
24        // Network notes must be public.
25        if note.metadata().note_type() != NoteType::Public {
26            return Err(NetworkAccountTargetError::NoteNotPublic(note.metadata().note_type()));
27        }
28
29        // Validate that the attachment is a valid NetworkAccountTarget.
30        NetworkAccountTarget::try_from(note.metadata().attachment())?;
31        Ok(Self { note })
32    }
33
34    /// Consumes `self` and returns the underlying [`Note`].
35    pub fn into_note(self) -> Note {
36        self.note
37    }
38
39    /// Returns a reference to the underlying [`Note`].
40    pub fn as_note(&self) -> &Note {
41        &self.note
42    }
43
44    /// Returns the [`NoteMetadata`] of the underlying note.
45    pub fn metadata(&self) -> &NoteMetadata {
46        self.note.metadata()
47    }
48
49    /// Returns the target network [`AccountId`].
50    pub fn target_account_id(&self) -> AccountId {
51        self.target().target_id()
52    }
53
54    /// Returns the decoded [`NetworkAccountTarget`] attachment.
55    pub fn target(&self) -> NetworkAccountTarget {
56        NetworkAccountTarget::try_from(self.note.metadata().attachment())
57            .expect("AccountTargetNetworkNote guarantees valid NetworkAccountTarget attachment")
58    }
59
60    /// Returns the [`NoteExecutionHint`] from the decoded [`NetworkAccountTarget`] attachment.
61    pub fn execution_hint(&self) -> NoteExecutionHint {
62        self.target().execution_hint()
63    }
64
65    /// Returns the raw [`NoteAttachment`] from the note metadata.
66    pub fn attachment(&self) -> &NoteAttachment {
67        self.metadata().attachment()
68    }
69
70    /// Returns the [`NoteType`] of the underlying note.
71    pub fn note_type(&self) -> NoteType {
72        self.metadata().note_type()
73    }
74}
75
76/// Convenience helpers for [`Note`]s that may target a network account.
77pub trait NetworkNoteExt {
78    /// Returns `true` if this note is public and its attachment decodes as a
79    /// [`NetworkAccountTarget`].
80    fn is_network_note(&self) -> bool;
81
82    /// Consumes `self` and returns an [`AccountTargetNetworkNote`], or an error if the attachment
83    /// is not a valid target.
84    fn into_account_target_network_note(
85        self,
86    ) -> Result<AccountTargetNetworkNote, NetworkAccountTargetError>;
87}
88
89impl NetworkNoteExt for Note {
90    fn is_network_note(&self) -> bool {
91        self.metadata().note_type() == NoteType::Public
92            && NetworkAccountTarget::try_from(self.metadata().attachment()).is_ok()
93    }
94
95    fn into_account_target_network_note(
96        self,
97    ) -> Result<AccountTargetNetworkNote, NetworkAccountTargetError> {
98        AccountTargetNetworkNote::new(self)
99    }
100}
101
102impl TryFrom<Note> for AccountTargetNetworkNote {
103    type Error = NetworkAccountTargetError;
104
105    fn try_from(note: Note) -> Result<Self, Self::Error> {
106        Self::new(note)
107    }
108}