use miden_client::note::{NoteDetails as NativeNoteDetails, NoteId as NativeNoteId};
use miden_client::notes::NoteFile as NativeNoteFile;
use miden_client::{Deserializable, Serializable};
use wasm_bindgen::prelude::*;
use super::input_note::InputNote;
use super::note::Note;
use super::output_note::OutputNote;
use crate::js_error_with_context;
use crate::models::note_details::NoteDetails;
use crate::models::note_id::NoteId;
use crate::models::note_inclusion_proof::NoteInclusionProof;
use crate::models::note_tag::NoteTag;
#[wasm_bindgen(inspectable)]
pub struct NoteFile {
pub(crate) inner: NativeNoteFile,
}
#[wasm_bindgen]
impl NoteFile {
#[wasm_bindgen(js_name = noteType)]
pub fn note_type(&self) -> String {
match &self.inner {
NativeNoteFile::NoteId(_) => "NoteId".to_owned(),
NativeNoteFile::NoteDetails { .. } => "NoteDetails".to_owned(),
NativeNoteFile::NoteWithProof(..) => "NoteWithProof".to_owned(),
}
}
#[wasm_bindgen(js_name = "noteId")]
pub fn note_id(&self) -> NoteId {
match &self.inner {
NativeNoteFile::NoteId(note_id) => (*note_id).into(),
NativeNoteFile::NoteDetails { details, .. } => details.id().into(),
NativeNoteFile::NoteWithProof(note, _) => note.id().into(),
}
}
#[wasm_bindgen(js_name = "noteDetails")]
pub fn note_details(&self) -> Option<NoteDetails> {
match &self.inner {
NativeNoteFile::NoteDetails { details, .. } => Some(details.into()),
_ => None,
}
}
pub fn note(&self) -> Option<Note> {
match &self.inner {
NativeNoteFile::NoteWithProof(note, _) => Some(note.into()),
_ => None,
}
}
#[wasm_bindgen(js_name = "inclusionProof")]
pub fn inclusion_proof(&self) -> Option<NoteInclusionProof> {
match &self.inner {
NativeNoteFile::NoteWithProof(_, proof) => Some(proof.into()),
_ => None,
}
}
#[wasm_bindgen(js_name = "afterBlockNum")]
pub fn after_block_num(&self) -> Option<u32> {
match &self.inner {
NativeNoteFile::NoteDetails { after_block_num, .. } => Some(after_block_num.as_u32()),
_ => None,
}
}
#[wasm_bindgen(js_name = "noteTag")]
pub fn note_tag(&self) -> Option<NoteTag> {
match &self.inner {
NativeNoteFile::NoteDetails { tag, .. } => tag.map(Into::into),
_ => None,
}
}
pub fn nullifier(&self) -> Option<String> {
match &self.inner {
NativeNoteFile::NoteDetails { details, .. } => Some(details.nullifier().to_hex()),
NativeNoteFile::NoteWithProof(note, _) => Some(note.nullifier().to_hex()),
NativeNoteFile::NoteId(_) => None,
}
}
#[wasm_bindgen(js_name = serialize)]
pub fn serialize(&self) -> Vec<u8> {
let mut buffer = vec![];
self.inner.write_into(&mut buffer);
buffer
}
#[wasm_bindgen(js_name = deserialize)]
pub fn deserialize(bytes: &[u8]) -> Result<Self, JsValue> {
let deserialized = NativeNoteFile::read_from_bytes(bytes)
.map_err(|err| js_error_with_context(err, "notefile deserialization failed"))?;
Ok(Self { inner: deserialized })
}
#[wasm_bindgen(js_name = fromInputNote)]
pub fn from_input_note(note: &InputNote) -> Self {
if let Some(inclusion_proof) = note.proof() {
Self {
inner: NativeNoteFile::NoteWithProof(note.note().into(), inclusion_proof.into()),
}
} else {
let assets = note.note().assets();
let recipient = note.note().recipient();
let details = NativeNoteDetails::new(assets.into(), recipient.into());
Self { inner: details.into() }
}
}
#[wasm_bindgen(js_name = "fromOutputNote")]
pub fn from_output_note(note: &OutputNote) -> Self {
let native_note = note.note();
match native_note.recipient() {
Some(recipient) => {
let assets = native_note.assets();
let details = NativeNoteDetails::new(assets.clone(), recipient.clone());
Self { inner: details.into() }
},
None => Self { inner: native_note.id().into() },
}
}
#[wasm_bindgen(js_name = fromNoteDetails)]
pub fn from_note_details(note_details: &NoteDetails) -> Self {
note_details.into()
}
#[wasm_bindgen(js_name = fromNoteId)]
pub fn from_note_id(note_details: &NoteId) -> Self {
note_details.into()
}
}
impl From<NativeNoteFile> for NoteFile {
fn from(note_file: NativeNoteFile) -> Self {
NoteFile { inner: note_file }
}
}
impl From<NoteFile> for NativeNoteFile {
fn from(note_file: NoteFile) -> Self {
note_file.inner
}
}
impl From<&NoteDetails> for NoteFile {
fn from(details: &NoteDetails) -> Self {
let note_details: NativeNoteDetails = details.into();
Self { inner: note_details.into() }
}
}
impl From<&NoteId> for NoteFile {
fn from(note_id: &NoteId) -> Self {
let note_id: NativeNoteId = note_id.into();
NoteFile { inner: note_id.into() }
}
}