iop-node-wasm 0.0.16

WebAssembly bindings to the node implementation for Hydraledger
Documentation
use super::*;

#[wasm_bindgen(js_name = MorpheusState)]
pub struct JsMorpheusState {
    inner: MorpheusState,
}

#[wasm_bindgen(js_class = MorpheusState)]
impl JsMorpheusState {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Result<JsMorpheusState, JsValue> {
        let inner = MorpheusState::default();
        Ok(Self { inner })
    }

    #[wasm_bindgen(getter = corrupted)]
    pub fn is_corrupted(&self) -> bool {
        self.inner.is_corrupted()
    }

    #[wasm_bindgen(js_name = lastBlockHeight)]
    pub fn last_seen_height(&self) -> Result<BlockHeight, JsValue> {
        let state = self.inner.state().map_err_to_js()?;
        Ok(state.last_seen_height())
    }

    #[wasm_bindgen(js_name = isConfirmed)]
    pub fn is_confirmed(&self, txid: &str) -> Result<Option<bool>, JsValue> {
        let state = self.inner.state().map_err_to_js()?;
        Ok(state.is_confirmed(txid))
    }

    #[wasm_bindgen(js_name = beforeProofExistsAt)]
    pub fn before_proof_exists_at(
        &self, content_id: &str, height_opt: Option<BlockHeight>,
    ) -> Result<bool, JsValue> {
        if let Some(height) = height_opt {
            Self::check_height(height)?;
        }
        let state = self.inner.state().map_err_to_js()?;
        Ok(state.before_proof_exists_at(content_id, height_opt))
    }

    #[wasm_bindgen(js_name = beforeProofHistory)]
    pub fn before_proof_history(&self, content_id: &str) -> Result<JsValue, JsValue> {
        let state = self.inner.state().map_err_to_js()?;
        let history = state.before_proof_history(content_id);
        let js_history = JsValue::from_serde(&history).map_err_to_js()?;
        Ok(js_history)
    }

    #[wasm_bindgen(js_name = getTransactionHistory)]
    pub fn get_tx_ids(
        &self, did: &str, include_attempts: bool, from_height_inc: BlockHeight,
        until_height_inc: Option<BlockHeight>,
    ) -> Result<JsValue, JsValue> {
        if let Some(height) = until_height_inc {
            Self::check_height(height)?;
        }
        let state = self.inner.state().map_err_to_js()?;
        let js_vec_opt = state
            .get_tx_ids(did, include_attempts, from_height_inc, until_height_inc)
            .map(|a| JsValue::from_serde(&a.collect::<Vec<_>>()))
            .unwrap_or_else(|| JsValue::from_serde(&([] as [TransactionIdWithHeight; 0])));
        js_vec_opt.map_err_to_js()
    }

    #[wasm_bindgen(js_name = lastTxId)]
    pub fn last_tx_id(&self, did: &str) -> Result<Option<String>, JsValue> {
        let state = self.inner.state().map_err_to_js()?;
        let height_opt = state.last_tx_id(did).map(|t| t.transaction_id.clone());
        Ok(height_opt)
    }

    #[wasm_bindgen(js_name = getDidDocumentAt)]
    pub fn get_doc_at(
        &self, did_data: &str, height_opt: Option<BlockHeight>,
    ) -> Result<JsValue, JsValue> {
        if let Some(height) = height_opt {
            Self::check_height(height)?;
        }
        let state = self.inner.state().map_err_to_js()?;
        let doc = state.get_doc_at(did_data, height_opt).map_err_to_js()?;
        let js_doc = JsValue::from_serde(&doc).map_err_to_js()?;
        Ok(js_doc)
    }

    #[wasm_bindgen(js_name = dryRun)]
    pub fn dry_run(&self, asset: &JsValue) -> Result<Vec<JsValue>, JsValue> {
        let asset: MorpheusAsset = asset.into_serde().map_err_to_js()?;
        let errs = self.inner.dry_run(&asset).map_err_to_js()?;
        let js_errs = errs
            .iter()
            .try_fold(
                Vec::<JsValue>::with_capacity(errs.len()),
                |mut v, err| -> serde_json::Result<_> {
                    v.push(JsValue::from_serde(err)?);
                    Ok(v)
                },
            )
            .map_err_to_js()?;
        Ok(js_errs)
    }

    fn check_height(height: BlockHeight) -> Result<(), JsValue> {
        if height > i32::MAX as u32 {
            return Err(JsValue::from(format!("Blockheight cannot be negative: {}", height)));
        }
        Ok(())
    }

    #[wasm_bindgen(js_name = blockApplying)]
    pub fn block_applying(&mut self, height: BlockHeight) -> Result<(), JsValue> {
        Self::check_height(height)?;
        self.inner.block_applying(height).map_err_to_js()
    }

    #[wasm_bindgen(js_name = applyTransaction)]
    pub fn apply_transaction(&mut self, txid: &str, asset: &JsValue) -> Result<(), JsValue> {
        let asset: MorpheusAsset = asset.into_serde().map_err_to_js()?;
        self.inner.apply_transaction(txid, &asset).map_err_to_js()
    }

    #[wasm_bindgen(js_name = blockReverting)]
    pub fn block_reverting(&mut self, height: BlockHeight) -> Result<(), JsValue> {
        Self::check_height(height)?;
        self.inner.block_reverting(height).map_err_to_js()
    }

    #[wasm_bindgen(js_name = revertTransaction)]
    pub fn revert_transaction(&mut self, txid: &str, asset: &JsValue) -> Result<(), JsValue> {
        let asset: MorpheusAsset = asset.into_serde().map_err_to_js()?;
        self.inner.revert_transaction(txid, &asset).map_err_to_js()
    }
}

impl Wraps<MorpheusState> for JsMorpheusState {
    fn inner(&self) -> &MorpheusState {
        &self.inner
    }
}

impl From<MorpheusState> for JsMorpheusState {
    fn from(inner: MorpheusState) -> Self {
        Self { inner }
    }
}