1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use miden_client::{store::NoteFilter, utils::Serializable};
use miden_objects::{notes::NoteFile, Digest};
use wasm_bindgen::prelude::*;

use crate::WebClient;

#[derive(Clone, Debug)]
pub enum ExportType {
    Id,
    Full,
    Partial,
}

#[wasm_bindgen]
impl WebClient {
    pub async fn export_note(
        &mut self,
        note_id: String,
        export_type: String,
    ) -> Result<JsValue, JsValue> {
        if let Some(client) = self.get_mut_inner() {
            let note_id = Digest::try_from(note_id)
                .map_err(|err| {
                    JsValue::from_str(&format!("Failed to parse input note id: {}", err))
                })?
                .into();

            let mut output_notes =
                client.get_output_notes(NoteFilter::Unique(note_id)).await.map_err(|err| {
                    JsValue::from_str(&format!("Failed to get output notes: {}", err))
                })?;

            let output_note =
                output_notes.pop().ok_or_else(|| JsValue::from_str("No output note found"))?;

            let export_type = match export_type.as_str() {
                "Id" => ExportType::Id,
                "Full" => ExportType::Full,
                "Partial" => ExportType::Partial,
                _ => ExportType::Partial,
            };

            let note_file = match export_type {
                ExportType::Id => NoteFile::NoteId(output_note.id()),
                ExportType::Full => match output_note.inclusion_proof() {
                    Some(inclusion_proof) => NoteFile::NoteWithProof(
                        output_note.clone().try_into().map_err(|err| {
                            JsValue::from_str(&format!("Failed to convert output note: {}", err))
                        })?,
                        inclusion_proof.clone(),
                    ),
                    None => return Err(JsValue::from_str("Note does not have inclusion proof")),
                },
                ExportType::Partial => NoteFile::NoteDetails {
                    details: output_note.clone().try_into().map_err(|err| {
                        JsValue::from_str(&format!("Failed to convert output note: {}", err))
                    })?,
                    after_block_num: client.get_sync_height().await.map_err(|err| {
                        JsValue::from_str(&format!("Failed to get sync height: {}", err))
                    })?,
                    tag: Some(output_note.metadata().tag()),
                },
            };

            let input_note_bytes = note_file.to_bytes();

            let serialized_input_note_bytes = serde_wasm_bindgen::to_value(&input_note_bytes)
                .map_err(|_| JsValue::from_str("Serialization error"))?;

            Ok(serialized_input_note_bytes)
        } else {
            Err(JsValue::from_str("Client not initialized"))
        }
    }
}