use js_export_macro::js_export;
use miden_client::crypto::RandomCoin;
use miden_client::note::{
NoteRecipient as NativeNoteRecipient,
NoteScript as NativeNoteScript,
NoteStorage as NativeNoteStorage,
};
use miden_client::{Felt as NativeFelt, Word as NativeWord};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
use super::note_script::NoteScript;
use super::note_storage::NoteStorage;
use super::word::Word;
use crate::models::miden_arrays::NoteRecipientArray as RecipientArray;
#[derive(Clone)]
#[js_export]
pub struct NoteRecipient(NativeNoteRecipient);
#[js_export]
impl NoteRecipient {
#[js_export(constructor)]
pub fn new(
serial_num: &Word,
note_script: &NoteScript,
storage: &NoteStorage,
) -> NoteRecipient {
let native_serial_num: NativeWord = serial_num.into();
let native_note_script: NativeNoteScript = note_script.into();
let native_note_storage: NativeNoteStorage = storage.into();
let native_note_recipient =
NativeNoteRecipient::new(native_serial_num, native_note_script, native_note_storage);
NoteRecipient(native_note_recipient)
}
#[js_export(js_name = "fromScript")]
pub fn from_script(note_script: &NoteScript, storage: &NoteStorage) -> NoteRecipient {
let mut rng = StdRng::from_os_rng();
let coin_seed: [u64; 4] = rng.random();
let mut rng = RandomCoin::new(coin_seed.map(NativeFelt::new_unchecked).into());
let serial_num: NativeWord = [rng.draw(), rng.draw(), rng.draw(), rng.draw()].into();
let native = NativeNoteRecipient::new(serial_num, note_script.into(), storage.into());
NoteRecipient(native)
}
pub fn digest(&self) -> Word {
self.0.digest().into()
}
#[js_export(js_name = "serialNum")]
pub fn serial_num(&self) -> Word {
self.0.serial_num().into()
}
pub fn script(&self) -> NoteScript {
self.0.script().into()
}
pub fn storage(&self) -> NoteStorage {
self.0.storage().into()
}
}
impl From<NativeNoteRecipient> for NoteRecipient {
fn from(native_note_recipient: NativeNoteRecipient) -> Self {
NoteRecipient(native_note_recipient)
}
}
impl From<&NativeNoteRecipient> for NoteRecipient {
fn from(native_note_recipient: &NativeNoteRecipient) -> Self {
NoteRecipient(native_note_recipient.clone())
}
}
impl From<NoteRecipient> for NativeNoteRecipient {
fn from(note_recipient: NoteRecipient) -> Self {
note_recipient.0
}
}
impl From<&NoteRecipient> for NativeNoteRecipient {
fn from(note_recipient: &NoteRecipient) -> Self {
note_recipient.0.clone()
}
}
impl From<&RecipientArray> for Vec<NativeNoteRecipient> {
fn from(recipient_array: &RecipientArray) -> Self {
recipient_array.iter().map(NativeNoteRecipient::from).collect()
}
}
impl_napi_from_value!(NoteRecipient);