diff --git a/bindings/cashu-ffi/src/cashu.udl b/bindings/cashu-ffi/src/cashu.udl index 216e4c71..ad17d216 100644 --- a/bindings/cashu-ffi/src/cashu.udl +++ b/bindings/cashu-ffi/src/cashu.udl @@ -31,8 +31,11 @@ interface Secret { sequence as_bytes(); }; -// NUT00 +interface MintQuoteInfo { + constructor(string id, Amount amount, string unit, Bolt11Invoice? request, boolean paid, u64 boolean); +}; +// NUT00 interface PublicKey { [Throws=CashuError, Name=from_hex] diff --git a/bindings/cashu-ffi/src/lib.rs b/bindings/cashu-ffi/src/lib.rs index ac62e339..c19a6118 100644 --- a/bindings/cashu-ffi/src/lib.rs +++ b/bindings/cashu-ffi/src/lib.rs @@ -29,8 +29,7 @@ mod ffi { pub use crate::nuts::nut06::{MintInfo, MintVersion}; pub use crate::nuts::nut07::{CheckSpendableRequest, CheckSpendableResponse}; pub use crate::nuts::nut08::{MeltBolt11Request, MeltBolt11Response}; - pub use crate::types::amount::Amount; - pub use crate::types::{Bolt11Invoice, KeySetInfo, Secret}; + pub use crate::types::{Amount, Bolt11Invoice, KeySetInfo, MintQuoteInfo, Secret}; // UDL uniffi::include_scaffolding!("cashu"); diff --git a/bindings/cashu-ffi/src/types/mint_quote_info.rs b/bindings/cashu-ffi/src/types/mint_quote_info.rs new file mode 100644 index 00000000..838e3071 --- /dev/null +++ b/bindings/cashu-ffi/src/types/mint_quote_info.rs @@ -0,0 +1,47 @@ +use std::ops::Deref; +use std::str::FromStr; +use std::sync::Arc; + +use cashu::nuts::CurrencyUnit; +use cashu::types::MintQuoteInfo as MintQuoteInfoSdk; + +use crate::{Amount, Bolt11Invoice}; + +pub struct MintQuoteInfo { + inner: MintQuoteInfoSdk, +} + +impl Deref for MintQuoteInfo { + type Target = MintQuoteInfoSdk; + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl From for MintQuoteInfo { + fn from(inner: MintQuoteInfoSdk) -> MintQuoteInfo { + MintQuoteInfo { inner } + } +} + +impl MintQuoteInfo { + pub fn new( + id: String, + amount: Arc, + unit: String, + request: Option>, + paid: bool, + expiry: u64, + ) -> Self { + Self { + inner: MintQuoteInfoSdk { + id, + amount: amount.as_ref().deref().clone(), + unit: CurrencyUnit::from_str(&unit).unwrap(), + request: request.map(|r| r.as_ref().deref().clone()), + paid, + expiry, + }, + } + } +} diff --git a/bindings/cashu-ffi/src/types/mod.rs b/bindings/cashu-ffi/src/types/mod.rs index c35078c3..0bb5acbf 100644 --- a/bindings/cashu-ffi/src/types/mod.rs +++ b/bindings/cashu-ffi/src/types/mod.rs @@ -1,8 +1,11 @@ pub mod amount; pub mod bolt11_invoice; pub mod keyset_info; +pub mod mint_quote_info; pub mod secret; +pub use amount::Amount; pub use bolt11_invoice::Bolt11Invoice; pub use keyset_info::KeySetInfo; +pub use mint_quote_info::MintQuoteInfo; pub use secret::Secret; diff --git a/bindings/cashu-sdk-ffi/src/cashu_sdk.udl b/bindings/cashu-sdk-ffi/src/cashu_sdk.udl index a584092f..e3b36410 100644 --- a/bindings/cashu-sdk-ffi/src/cashu_sdk.udl +++ b/bindings/cashu-sdk-ffi/src/cashu_sdk.udl @@ -34,8 +34,11 @@ interface Secret { sequence as_bytes(); }; -// NUT00 +interface MintQuoteInfo { + constructor(string id, Amount amount, string unit, Bolt11Invoice? request, boolean paid, u64 boolean); +}; +// NUT00 interface PublicKey { [Throws=CashuError, Name=from_hex] @@ -299,9 +302,9 @@ interface Wallet { // [Throws=CashuSdkError] // ProofsStatus check_proofs_spent(sequence proofs); [Throws=CashuSdkError] - Token mint_token(Amount amount, string hash,CurrencyUnit? unit, string? memo); + Token mint_token(Amount amount, CurrencyUnit? unit, string? memo); [Throws=CashuSdkError] - sequence mint(Amount amount, string hash); + sequence mint(string quote); [Throws=CashuSdkError] sequence receive(string encoded_token); [Throws=CashuSdkError] diff --git a/bindings/cashu-sdk-ffi/src/lib.rs b/bindings/cashu-sdk-ffi/src/lib.rs index 2935e5af..18893f16 100644 --- a/bindings/cashu-sdk-ffi/src/lib.rs +++ b/bindings/cashu-sdk-ffi/src/lib.rs @@ -10,8 +10,9 @@ mod ffi { KeySetResponse, Keys, KeysResponse, MeltBolt11Request, MeltBolt11Response, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MintBolt11Request, MintBolt11Response, MintInfo, MintKeySet, MintProof, MintProofs, MintQuoteBolt11Request, - MintQuoteBolt11Response, MintVersion, Nut05MeltBolt11Request, Nut05MeltBolt11Response, - PreMintSecrets, Proof, PublicKey, Secret, SecretKey, SwapRequest, SwapResponse, Token, + MintQuoteBolt11Response, MintQuoteInfo, MintVersion, Nut05MeltBolt11Request, + Nut05MeltBolt11Response, PreMintSecrets, Proof, PublicKey, Secret, SecretKey, SwapRequest, + SwapResponse, Token, }; pub use crate::error::CashuSdkError; diff --git a/bindings/cashu-sdk-ffi/src/wallet.rs b/bindings/cashu-sdk-ffi/src/wallet.rs index 4d402f3b..0391a56c 100644 --- a/bindings/cashu-sdk-ffi/src/wallet.rs +++ b/bindings/cashu-sdk-ffi/src/wallet.rs @@ -1,7 +1,7 @@ use std::ops::Deref; -use std::sync::Arc; +use std::sync::{Arc, RwLock}; -use cashu_ffi::{BlindedSignature, CurrencyUnit, PreMintSecrets, Proof, Token}; +use cashu_ffi::{BlindedSignature, CurrencyUnit, MintQuoteInfo, PreMintSecrets, Proof, Token}; use cashu_sdk::client::minreq_client::HttpClient; use cashu_sdk::types::ProofsStatus; use cashu_sdk::url::UncheckedUrl; @@ -16,24 +16,31 @@ use crate::{Amount, Keys}; static RUNTIME: Lazy = Lazy::new(|| Runtime::new().expect("Can't start Tokio runtime")); pub struct Wallet { - inner: WalletSdk, + inner: RwLock>, } impl Wallet { - pub fn new(mint_url: &str, mint_keys: Arc) -> Self { + pub fn new(mint_url: &str, mint_keys: Arc, quotes: Vec>) -> Self { let client = HttpClient {}; Self { inner: WalletSdk::new( client, UncheckedUrl::new(mint_url), + quotes + .into_iter() + .map(|q| q.as_ref().deref().clone()) + .collect(), mint_keys.as_ref().deref().clone(), - ), + ) + .into(), } } pub fn check_proofs_spent(&self, proofs: Vec>) -> Result> { let proofs = RUNTIME.block_on(async { self.inner + .read() + .unwrap() .check_proofs_spent(proofs.iter().map(|p| p.as_ref().deref().clone()).collect()) .await })?; @@ -44,33 +51,29 @@ impl Wallet { pub fn mint_token( &self, amount: Arc, - hash: String, unit: Option, memo: Option, ) -> Result> { let token = RUNTIME.block_on(async { self.inner - .mint_token( - *amount.as_ref().deref(), - &hash, - memo, - unit.map(|u| u.into()), - ) + .write() + .unwrap() + .mint_token(*amount.as_ref().deref(), memo, unit.map(|u| u.into())) .await })?; Ok(Arc::new(token.into())) } - pub fn mint(&self, amount: Arc, hash: String) -> Result>> { - let proofs = - RUNTIME.block_on(async { self.inner.mint(*amount.as_ref().deref(), &hash).await })?; + pub fn mint(&self, quote: String) -> Result>> { + let proofs = RUNTIME.block_on(async { self.inner.write().unwrap().mint("e).await })?; Ok(proofs.into_iter().map(|p| Arc::new(p.into())).collect()) } pub fn receive(&self, encoded_token: String) -> Result>> { - let proofs = RUNTIME.block_on(async { self.inner.receive(&encoded_token).await })?; + let proofs = RUNTIME + .block_on(async { self.inner.write().unwrap().receive(&encoded_token).await })?; Ok(proofs.into_iter().map(|p| Arc::new(p.into())).collect()) } @@ -82,6 +85,8 @@ impl Wallet { ) -> Result>> { Ok(self .inner + .read() + .unwrap() .process_split_response( blinded_messages.as_ref().deref().clone(), promises.iter().map(|p| p.as_ref().into()).collect(), @@ -94,6 +99,8 @@ impl Wallet { pub fn send(&self, amount: Arc, proofs: Vec>) -> Result> { let send_proofs = RUNTIME.block_on(async { self.inner + .read() + .unwrap() .send( *amount.as_ref().deref(), proofs.iter().map(|p| p.as_ref().deref().clone()).collect(), @@ -112,6 +119,8 @@ impl Wallet { ) -> Result> { let melted = RUNTIME.block_on(async { self.inner + .write() + .unwrap() .melt( quote, proofs.iter().map(|p| p.as_ref().deref().clone()).collect(), @@ -129,7 +138,7 @@ impl Wallet { unit: Option, memo: Option, ) -> Result { - Ok(self.inner.proofs_to_token( + Ok(self.inner.read().unwrap().proofs_to_token( proofs.iter().map(|p| p.as_ref().deref().clone()).collect(), memo, unit.map(|u| u.into()),