use miden_crypto::Word;
use miden_crypto::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
use miden_processor::DeserializationError;
use crate::account::AccountId;
use crate::{Felt, Hasher, NoteError, WORD_SIZE, ZERO};
mod assets;
pub use assets::NoteAssets;
mod details;
pub use details::NoteDetails;
mod header;
pub use header::{NoteHeader, compute_note_commitment};
mod inputs;
pub use inputs::NoteInputs;
mod metadata;
pub use metadata::NoteMetadata;
mod execution_hint;
pub use execution_hint::{AfterBlockNumber, NoteExecutionHint};
mod note_id;
pub use note_id::NoteId;
mod note_tag;
pub use note_tag::{NoteExecutionMode, NoteTag};
mod note_type;
pub use note_type::NoteType;
mod nullifier;
pub use nullifier::Nullifier;
mod location;
pub use location::{NoteInclusionProof, NoteLocation};
mod partial;
pub use partial::PartialNote;
mod recipient;
pub use recipient::NoteRecipient;
mod script;
pub use script::NoteScript;
mod file;
pub use file::NoteFile;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Note {
header: NoteHeader,
details: NoteDetails,
nullifier: Nullifier,
}
impl Note {
pub fn new(assets: NoteAssets, metadata: NoteMetadata, recipient: NoteRecipient) -> Self {
let details = NoteDetails::new(assets, recipient);
let header = NoteHeader::new(details.id(), metadata);
let nullifier = details.nullifier();
Self { header, details, nullifier }
}
pub fn header(&self) -> &NoteHeader {
&self.header
}
pub fn id(&self) -> NoteId {
self.header.id()
}
pub fn metadata(&self) -> &NoteMetadata {
self.header.metadata()
}
pub fn assets(&self) -> &NoteAssets {
self.details.assets()
}
pub fn serial_num(&self) -> Word {
self.details.serial_num()
}
pub fn script(&self) -> &NoteScript {
self.details.script()
}
pub fn inputs(&self) -> &NoteInputs {
self.details.inputs()
}
pub fn recipient(&self) -> &NoteRecipient {
self.details.recipient()
}
pub fn nullifier(&self) -> Nullifier {
self.nullifier
}
pub fn commitment(&self) -> Word {
self.header.commitment()
}
pub fn is_network_note(&self) -> bool {
self.metadata().tag().execution_mode() == NoteExecutionMode::Network
}
}
impl AsRef<NoteRecipient> for Note {
fn as_ref(&self) -> &NoteRecipient {
self.recipient()
}
}
impl From<&Note> for NoteHeader {
fn from(note: &Note) -> Self {
note.header
}
}
impl From<Note> for NoteHeader {
fn from(note: Note) -> Self {
note.header
}
}
impl From<&Note> for NoteDetails {
fn from(note: &Note) -> Self {
note.details.clone()
}
}
impl From<Note> for NoteDetails {
fn from(note: Note) -> Self {
note.details
}
}
impl From<Note> for PartialNote {
fn from(note: Note) -> Self {
let (assets, recipient, ..) = note.details.into_parts();
PartialNote::new(*note.header.metadata(), recipient.digest(), assets)
}
}
impl From<&Note> for PartialNote {
fn from(note: &Note) -> Self {
PartialNote::new(
*note.header.metadata(),
note.details.recipient().digest(),
note.details.assets().clone(),
)
}
}
impl Serializable for Note {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let Self {
header,
details,
nullifier: _,
} = self;
header.metadata().write_into(target);
details.write_into(target);
}
}
impl Deserializable for Note {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
let metadata = NoteMetadata::read_from(source)?;
let details = NoteDetails::read_from(source)?;
let (assets, recipient) = details.into_parts();
Ok(Self::new(assets, metadata, recipient))
}
}