瀏覽代碼

`bindings/cashu-js` `nut07` and `nut08`

thesimplekid 1 年之前
父節點
當前提交
405da06078

+ 19 - 12
bindings/cashu-ffi/src/nuts/nut08/mod.rs

@@ -62,6 +62,25 @@ pub struct MeltResponse {
     inner: MeltResponseSdk,
 }
 
+impl Deref for MeltResponse {
+    type Target = MeltResponseSdk;
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl From<cashu::nuts::nut08::MeltResponse> for MeltResponse {
+    fn from(inner: cashu::nuts::nut08::MeltResponse) -> MeltResponse {
+        MeltResponse { inner }
+    }
+}
+
+impl From<MeltResponse> for cashu::nuts::nut08::MeltResponse {
+    fn from(res: MeltResponse) -> cashu::nuts::nut08::MeltResponse {
+        res.inner
+    }
+}
+
 impl MeltResponse {
     pub fn new(
         paid: bool,
@@ -93,15 +112,3 @@ impl MeltResponse {
             .map(|change| change.into_iter().map(|bs| Arc::new(bs.into())).collect())
     }
 }
-
-impl From<cashu::nuts::nut08::MeltResponse> for MeltResponse {
-    fn from(inner: cashu::nuts::nut08::MeltResponse) -> MeltResponse {
-        MeltResponse { inner }
-    }
-}
-
-impl From<MeltResponse> for cashu::nuts::nut08::MeltResponse {
-    fn from(res: MeltResponse) -> cashu::nuts::nut08::MeltResponse {
-        res.inner
-    }
-}

+ 2 - 1
bindings/cashu-js/Cargo.toml

@@ -15,7 +15,8 @@ cashu = { path = "../../crates/cashu"}
 js-sys = "0.3.64"
 serde-wasm-bindgen = "0.6.0"
 serde_json.workspace = true
-wasm-bindgen = "0.2.87"
+serde.workspace = true
+wasm-bindgen = { version = "0.2.87", features = ["serde-serialize"] }
 wasm-bindgen-futures = "0.4.37"
 
 [package.metadata.wasm-pack.profile.release]

+ 2 - 0
bindings/cashu-js/src/nuts/mod.rs

@@ -5,3 +5,5 @@ mod nut03;
 mod nut04;
 mod nut05;
 mod nut06;
+mod nut07;
+mod nut08;

+ 107 - 0
bindings/cashu-js/src/nuts/nut07.rs

@@ -0,0 +1,107 @@
+use std::ops::Deref;
+
+use cashu::nuts::nut07::{CheckSpendableRequest, CheckSpendableResponse};
+use wasm_bindgen::prelude::*;
+
+use crate::error::{into_err, Result};
+
+#[wasm_bindgen(js_name = CheckSpendableRequest)]
+pub struct JsCheckSpendableRequest {
+    inner: CheckSpendableRequest,
+}
+
+impl Deref for JsCheckSpendableRequest {
+    type Target = CheckSpendableRequest;
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl From<CheckSpendableRequest> for JsCheckSpendableRequest {
+    fn from(inner: CheckSpendableRequest) -> JsCheckSpendableRequest {
+        JsCheckSpendableRequest { inner }
+    }
+}
+
+#[wasm_bindgen(js_class = CheckSpendable)]
+impl JsCheckSpendableRequest {
+    // REVIEW: Use into serde
+    #[wasm_bindgen(constructor)]
+    pub fn new(proofs: String) -> Result<JsCheckSpendableRequest> {
+        let proofs = serde_json::from_str(&proofs).map_err(into_err)?;
+
+        Ok(JsCheckSpendableRequest {
+            inner: CheckSpendableRequest { proofs },
+        })
+    }
+
+    /// Get Proofs
+    #[wasm_bindgen(getter)]
+    // REVIEW: INTO Serde
+    pub fn proofs(&self) -> Result<String> {
+        Ok(serde_json::to_string(&self.inner.proofs).map_err(into_err)?)
+    }
+}
+
+#[wasm_bindgen(js_name = CheckSpendableResponse)]
+pub struct JsCheckSpendableResponse {
+    inner: CheckSpendableResponse,
+}
+
+impl Deref for JsCheckSpendableResponse {
+    type Target = CheckSpendableResponse;
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl From<CheckSpendableResponse> for JsCheckSpendableResponse {
+    fn from(inner: CheckSpendableResponse) -> JsCheckSpendableResponse {
+        JsCheckSpendableResponse { inner }
+    }
+}
+
+#[wasm_bindgen(js_class = CheckSpendableResponse)]
+impl JsCheckSpendableResponse {
+    #[wasm_bindgen(constructor)]
+    pub fn new(
+        js_spendable: Box<[JsValue]>,
+        js_pending: Box<[JsValue]>,
+    ) -> Result<JsCheckSpendableResponse> {
+        let spendable: Vec<bool> = js_spendable.iter().flat_map(|s| s.as_bool()).collect();
+
+        if spendable.len().ne(&js_spendable.len()) {
+            return Err(JsValue::from_str("Wrong value"));
+        }
+
+        let pending: Vec<bool> = js_pending.iter().flat_map(|p| p.as_bool()).collect();
+
+        if pending.len().ne(&js_pending.len()) {
+            return Err(JsValue::from_str("Wrong value"));
+        }
+
+        Ok(JsCheckSpendableResponse {
+            inner: CheckSpendableResponse { spendable, pending },
+        })
+    }
+
+    /// Get Pending
+    #[wasm_bindgen(getter)]
+    pub fn pending(&self) -> Box<[JsValue]> {
+        self.inner
+            .pending
+            .iter()
+            .map(|p| JsValue::from_bool(*p))
+            .collect()
+    }
+
+    /// Get Spendable
+    #[wasm_bindgen(getter)]
+    pub fn spendable(&self) -> Box<[JsValue]> {
+        self.inner
+            .spendable
+            .iter()
+            .map(|s| JsValue::from_bool(*s))
+            .collect()
+    }
+}

+ 135 - 0
bindings/cashu-js/src/nuts/nut08.rs

@@ -0,0 +1,135 @@
+use std::ops::Deref;
+
+use cashu::nuts::{
+    nut00::{BlindedMessage, BlindedSignature, Proof},
+    nut08::{MeltRequest, MeltResponse},
+};
+use wasm_bindgen::prelude::*;
+
+use crate::{
+    error::{into_err, Result},
+    types::{JsAmount, JsBolt11Invoice},
+};
+
+#[wasm_bindgen(js_name = MeltRequest)]
+pub struct JsMeltRequest {
+    inner: MeltRequest,
+}
+
+impl Deref for JsMeltRequest {
+    type Target = MeltRequest;
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl From<MeltRequest> for JsMeltRequest {
+    fn from(inner: MeltRequest) -> JsMeltRequest {
+        JsMeltRequest { inner }
+    }
+}
+
+#[wasm_bindgen(js_class = MeltRequest)]
+impl JsMeltRequest {
+    #[wasm_bindgen(constructor)]
+    pub fn new(
+        proofs: JsValue,
+        invoice: JsBolt11Invoice,
+        outputs: JsValue,
+    ) -> Result<JsMeltRequest> {
+        let proofs: Vec<Proof> = serde_wasm_bindgen::from_value(proofs).map_err(into_err)?;
+        let outputs: Option<Vec<BlindedMessage>> = if !outputs.is_null() {
+            Some(serde_wasm_bindgen::from_value(outputs).map_err(into_err)?)
+        } else {
+            None
+        };
+
+        Ok(JsMeltRequest {
+            inner: MeltRequest {
+                proofs,
+                pr: invoice.deref().clone(),
+                outputs,
+            },
+        })
+    }
+
+    /// Get Proofs
+    #[wasm_bindgen(getter)]
+    pub fn proofs(&self) -> Result<JsValue> {
+        Ok(serde_wasm_bindgen::to_value(&self.inner.proofs).map_err(into_err)?)
+    }
+
+    /// Get Invoice
+    #[wasm_bindgen(getter)]
+    pub fn invoice(&self) -> JsBolt11Invoice {
+        self.inner.pr.clone().into()
+    }
+
+    /// Get outputs
+    #[wasm_bindgen(getter)]
+    pub fn outputs(&self) -> Result<JsValue> {
+        Ok(serde_wasm_bindgen::to_value(&self.inner.outputs).map_err(into_err)?)
+    }
+}
+
+#[wasm_bindgen(js_name = MeltResponse)]
+pub struct JsMeltResponse {
+    inner: MeltResponse,
+}
+
+impl Deref for JsMeltResponse {
+    type Target = MeltResponse;
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl From<MeltResponse> for JsMeltResponse {
+    fn from(inner: MeltResponse) -> JsMeltResponse {
+        JsMeltResponse { inner }
+    }
+}
+
+#[wasm_bindgen(js_class = MeltResponse)]
+impl JsMeltResponse {
+    #[wasm_bindgen(constructor)]
+    pub fn new(paid: bool, preimage: Option<String>, change: JsValue) -> Result<JsMeltResponse> {
+        let change: Option<Vec<BlindedSignature>> = if change.is_null() {
+            Some(serde_wasm_bindgen::from_value(change).map_err(into_err)?)
+        } else {
+            None
+        };
+
+        Ok(JsMeltResponse {
+            inner: MeltResponse {
+                paid,
+                preimage,
+                change,
+            },
+        })
+    }
+
+    /// Get Paid
+    #[wasm_bindgen(getter)]
+    pub fn paid(&self) -> bool {
+        self.inner.paid
+    }
+
+    /// Get Preimage
+    #[wasm_bindgen(getter)]
+    pub fn preimage(&self) -> Option<String> {
+        self.inner.preimage.clone()
+    }
+
+    /// Get Change
+    #[wasm_bindgen(getter)]
+    pub fn change(&self) -> Result<JsValue> {
+        Ok(serde_wasm_bindgen::to_value(&self.inner.change).map_err(into_err)?)
+    }
+
+    /// Change Amount
+    #[wasm_bindgen(js_name = "cahngeAmount")]
+    pub fn change_amount(&self) -> JsAmount {
+        self.inner.change_amount().into()
+    }
+}