diff --git a/bindings/cashu-sdk-js/src/client.rs b/bindings/cashu-sdk-js/src/client.rs new file mode 100644 index 00000000..ce9f2d98 --- /dev/null +++ b/bindings/cashu-sdk-js/src/client.rs @@ -0,0 +1,144 @@ +use std::ops::Deref; + +use cashu_js::nuts::nut00::JsBlindedMessages; +use cashu_js::nuts::nut01::JsKeys; +use cashu_js::nuts::nut02::JsKeySetsResponse; +use cashu_js::nuts::nut03::JsRequestMintResponse; +use cashu_js::nuts::nut04::JsPostMintResponse; +use cashu_js::nuts::nut05::JsCheckFeesResponse; +use cashu_js::nuts::nut06::{JsSplitRequest, JsSplitResponse}; +use cashu_js::nuts::nut07::JsCheckSpendableResponse; +use cashu_js::nuts::nut08::JsMeltResponse; +use cashu_js::nuts::nut09::JsMintInfo; +use cashu_js::types::{JsAmount, JsBolt11Invoice}; +use cashu_sdk::client::Client; +use wasm_bindgen::prelude::*; + +use crate::error::{into_err, Result}; + +#[wasm_bindgen(js_name = Client)] +pub struct JsClient { + inner: Client, +} + +impl Deref for JsClient { + type Target = Client; + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl From for JsClient { + fn from(inner: Client) -> JsClient { + JsClient { inner } + } +} + +#[wasm_bindgen(js_class = Client)] +impl JsClient { + #[wasm_bindgen(constructor)] + pub fn new(mint_url: String) -> Result { + Ok(JsClient { + inner: Client::new(&mint_url).map_err(into_err)?, + }) + } + + /// Get Keys [NUT-01] + #[wasm_bindgen(js_name = getKeys)] + pub async fn get_keys(&self) -> Result { + Ok(self.inner.get_keys().await.map_err(into_err)?.into()) + } + + /// Get Keys [NUT-01] + #[wasm_bindgen(js_name = getKeysets)] + pub async fn get_keysets(&self) -> Result { + Ok(self.inner.get_keysets().await.map_err(into_err)?.into()) + } + + /// Request Mint [NUT-03] + #[wasm_bindgen(js_name = requestMint)] + pub async fn request_mint(&self, amount: JsAmount) -> Result { + Ok(self + .inner + .request_mint(*amount.deref()) + .await + .map_err(into_err)? + .into()) + } + + /// Mint [NUT-04] + #[wasm_bindgen(js_name = mint)] + pub async fn mint( + &self, + blinded_messages: JsBlindedMessages, + hash: String, + ) -> Result { + Ok(self + .inner + .mint(blinded_messages.deref().clone(), &hash) + .await + .map_err(into_err)? + .into()) + } + + /// Check Max expected fee [NUT-05] + #[wasm_bindgen(js_name = check_fees)] + pub async fn check_fees(&self, invoice: JsBolt11Invoice) -> Result { + Ok(self + .inner + .check_fees(invoice.deref().clone()) + .await + .map_err(into_err)? + .into()) + } + + /// Melt [NUT-05] + #[wasm_bindgen(js_name = melt)] + pub async fn melt( + &self, + proofs: JsValue, + invoice: JsBolt11Invoice, + outputs: JsValue, + ) -> Result { + let proofs = serde_wasm_bindgen::from_value(proofs).map_err(into_err)?; + let outputs = if outputs.is_null() { + None + } else { + Some(serde_wasm_bindgen::from_value(outputs).map_err(into_err)?) + }; + Ok(self + .inner + .melt(proofs, invoice.deref().clone(), outputs) + .await + .map_err(into_err)? + .into()) + } + + /// Split [NUT-06] + #[wasm_bindgen(js_name = split)] + pub async fn split(&self, split_request: JsSplitRequest) -> Result { + Ok(self + .inner + .split(split_request.deref().clone()) + .await + .map_err(into_err)? + .into()) + } + + #[wasm_bindgen(js_name = checkSpendable)] + pub async fn check_spendable(&self, proofs: JsValue) -> Result { + let proofs = serde_wasm_bindgen::from_value(proofs).map_err(into_err)?; + + Ok(self + .inner + .check_spendable(&proofs) + .await + .map_err(into_err)? + .into()) + } + + #[wasm_bindgen(js_name = getInfo)] + pub async fn get_info(&self) -> Result { + Ok(self.inner.get_info().await.map_err(into_err)?.into()) + } +} diff --git a/bindings/cashu-sdk-js/src/lib.rs b/bindings/cashu-sdk-js/src/lib.rs index 13b147b6..3392f6f0 100644 --- a/bindings/cashu-sdk-js/src/lib.rs +++ b/bindings/cashu-sdk-js/src/lib.rs @@ -1,3 +1,5 @@ +mod client; mod error; mod mint; mod types; +mod wallet; diff --git a/bindings/cashu-sdk-js/src/wallet.rs b/bindings/cashu-sdk-js/src/wallet.rs new file mode 100644 index 00000000..3575c3ce --- /dev/null +++ b/bindings/cashu-sdk-js/src/wallet.rs @@ -0,0 +1,32 @@ +use std::ops::Deref; + +use cashu_sdk::wallet::Wallet; +use wasm_bindgen::prelude::*; + +use crate::error::{into_err, Result}; + +#[wasm_bindgen(js_name = Wallet)] +pub struct JsWallet { + inner: Wallet, +} + +impl Deref for JsWallet { + type Target = Wallet; + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl From for JsWallet { + fn from(inner: Wallet) -> JsWallet { + JsWallet { inner } + } +} + +#[wasm_bindgen(js_class = Wallet)] +impl JsWallet { + #[wasm_bindgen(constructor)] + pub fn new() -> Result { + todo!() + } +} diff --git a/crates/cashu-sdk/src/client/mod.rs b/crates/cashu-sdk/src/client/mod.rs index e5153857..0a501703 100644 --- a/crates/cashu-sdk/src/client/mod.rs +++ b/crates/cashu-sdk/src/client/mod.rs @@ -145,27 +145,6 @@ impl Client { let keys = minreq::get(url).send()?.json::()?; let keys: Keys = serde_json::from_str(&keys.to_string())?; - /* - let keys: BTreeMap = match serde_json::from_value(keys.clone()) { - Ok(keys) => keys, - Err(_err) => { - return Err(Error::CustomError(format!( - "url: {}, {}", - url, - serde_json::to_string(&keys)? - ))) - } - }; - - let mint_keys: BTreeMap = keys - .into_iter() - .filter_map(|(k, v)| { - let key = hex::decode(v).ok()?; - let public_key = PublicKey::from_sec1_bytes(&key).ok()?; - Some((k, public_key)) - }) - .collect(); - */ Ok(keys) }