iop_node_wasm/
morpheus.rs

1use super::*;
2
3#[wasm_bindgen(js_name = MorpheusState)]
4pub struct JsMorpheusState {
5    inner: MorpheusState,
6}
7
8#[wasm_bindgen(js_class = MorpheusState)]
9impl JsMorpheusState {
10    #[wasm_bindgen(constructor)]
11    pub fn new() -> Result<JsMorpheusState, JsValue> {
12        let inner = MorpheusState::default();
13        Ok(Self { inner })
14    }
15
16    #[wasm_bindgen(getter = corrupted)]
17    pub fn is_corrupted(&self) -> bool {
18        self.inner.is_corrupted()
19    }
20
21    #[wasm_bindgen(js_name = lastBlockHeight)]
22    pub fn last_seen_height(&self) -> Result<BlockHeight, JsValue> {
23        let state = self.inner.state().map_err_to_js()?;
24        Ok(state.last_seen_height())
25    }
26
27    #[wasm_bindgen(js_name = isConfirmed)]
28    pub fn is_confirmed(&self, txid: &str) -> Result<Option<bool>, JsValue> {
29        let state = self.inner.state().map_err_to_js()?;
30        Ok(state.is_confirmed(txid))
31    }
32
33    #[wasm_bindgen(js_name = beforeProofExistsAt)]
34    pub fn before_proof_exists_at(
35        &self, content_id: &str, height_opt: Option<BlockHeight>,
36    ) -> Result<bool, JsValue> {
37        if let Some(height) = height_opt {
38            Self::check_height(height)?;
39        }
40        let state = self.inner.state().map_err_to_js()?;
41        Ok(state.before_proof_exists_at(content_id, height_opt))
42    }
43
44    #[wasm_bindgen(js_name = beforeProofHistory)]
45    pub fn before_proof_history(&self, content_id: &str) -> Result<JsValue, JsValue> {
46        let state = self.inner.state().map_err_to_js()?;
47        let history = state.before_proof_history(content_id);
48        let js_history = JsValue::from_serde(&history).map_err_to_js()?;
49        Ok(js_history)
50    }
51
52    #[wasm_bindgen(js_name = getTransactionHistory)]
53    pub fn get_tx_ids(
54        &self, did: &str, include_attempts: bool, from_height_inc: BlockHeight,
55        until_height_inc: Option<BlockHeight>,
56    ) -> Result<JsValue, JsValue> {
57        if let Some(height) = until_height_inc {
58            Self::check_height(height)?;
59        }
60        let state = self.inner.state().map_err_to_js()?;
61        let js_vec_opt = state
62            .get_tx_ids(did, include_attempts, from_height_inc, until_height_inc)
63            .map(|a| JsValue::from_serde(&a.collect::<Vec<_>>()))
64            .unwrap_or_else(|| JsValue::from_serde(&([] as [TransactionIdWithHeight; 0])));
65        js_vec_opt.map_err_to_js()
66    }
67
68    #[wasm_bindgen(js_name = lastTxId)]
69    pub fn last_tx_id(&self, did: &str) -> Result<Option<String>, JsValue> {
70        let state = self.inner.state().map_err_to_js()?;
71        let height_opt = state.last_tx_id(did).map(|t| t.transaction_id.clone());
72        Ok(height_opt)
73    }
74
75    #[wasm_bindgen(js_name = getDidDocumentAt)]
76    pub fn get_doc_at(
77        &self, did_data: &str, height_opt: Option<BlockHeight>,
78    ) -> Result<JsValue, JsValue> {
79        if let Some(height) = height_opt {
80            Self::check_height(height)?;
81        }
82        let state = self.inner.state().map_err_to_js()?;
83        let doc = state.get_doc_at(did_data, height_opt).map_err_to_js()?;
84        let js_doc = JsValue::from_serde(&doc).map_err_to_js()?;
85        Ok(js_doc)
86    }
87
88    #[wasm_bindgen(js_name = dryRun)]
89    pub fn dry_run(&self, asset: &JsValue) -> Result<Vec<JsValue>, JsValue> {
90        let asset: MorpheusAsset = asset.into_serde().map_err_to_js()?;
91        let errs = self.inner.dry_run(&asset).map_err_to_js()?;
92        let js_errs = errs
93            .iter()
94            .try_fold(
95                Vec::<JsValue>::with_capacity(errs.len()),
96                |mut v, err| -> serde_json::Result<_> {
97                    v.push(JsValue::from_serde(err)?);
98                    Ok(v)
99                },
100            )
101            .map_err_to_js()?;
102        Ok(js_errs)
103    }
104
105    fn check_height(height: BlockHeight) -> Result<(), JsValue> {
106        if height > i32::MAX as u32 {
107            return Err(JsValue::from(format!("Blockheight cannot be negative: {}", height)));
108        }
109        Ok(())
110    }
111
112    #[wasm_bindgen(js_name = blockApplying)]
113    pub fn block_applying(&mut self, height: BlockHeight) -> Result<(), JsValue> {
114        Self::check_height(height)?;
115        self.inner.block_applying(height).map_err_to_js()
116    }
117
118    #[wasm_bindgen(js_name = applyTransaction)]
119    pub fn apply_transaction(&mut self, txid: &str, asset: &JsValue) -> Result<(), JsValue> {
120        let asset: MorpheusAsset = asset.into_serde().map_err_to_js()?;
121        self.inner.apply_transaction(txid, &asset).map_err_to_js()
122    }
123
124    #[wasm_bindgen(js_name = blockReverting)]
125    pub fn block_reverting(&mut self, height: BlockHeight) -> Result<(), JsValue> {
126        Self::check_height(height)?;
127        self.inner.block_reverting(height).map_err_to_js()
128    }
129
130    #[wasm_bindgen(js_name = revertTransaction)]
131    pub fn revert_transaction(&mut self, txid: &str, asset: &JsValue) -> Result<(), JsValue> {
132        let asset: MorpheusAsset = asset.into_serde().map_err_to_js()?;
133        self.inner.revert_transaction(txid, &asset).map_err_to_js()
134    }
135}
136
137impl Wraps<MorpheusState> for JsMorpheusState {
138    fn inner(&self) -> &MorpheusState {
139        &self.inner
140    }
141}
142
143impl From<MorpheusState> for JsMorpheusState {
144    fn from(inner: MorpheusState) -> Self {
145        Self { inner }
146    }
147}