diff --git a/bindings/cashu-ffi/src/cashu.udl b/bindings/cashu-ffi/src/cashu.udl index 7d3e6e51..270f42c6 100644 --- a/bindings/cashu-ffi/src/cashu.udl +++ b/bindings/cashu-ffi/src/cashu.udl @@ -213,7 +213,7 @@ interface MintVersion { }; interface MintInfo { - constructor(string? name, PublicKey? pubkey, MintVersion? version, string? description, string? description_long, sequence> contact, sequence nuts, string? motd); + constructor(string? name, PublicKey? pubkey, MintVersion? version, string? description, string? description_long, sequence>? contact, sequence nuts, string? motd); }; enum InvoiceStatus { @@ -221,4 +221,5 @@ enum InvoiceStatus { "Paid", "Expired", "InFlight" -}; \ No newline at end of file +}; + diff --git a/bindings/cashu-ffi/src/lib.rs b/bindings/cashu-ffi/src/lib.rs index 4226b912..6333823b 100644 --- a/bindings/cashu-ffi/src/lib.rs +++ b/bindings/cashu-ffi/src/lib.rs @@ -27,6 +27,7 @@ mod ffi { pub use crate::nuts::nut09::{MintInfo, MintVersion}; pub use crate::types::amount::Amount; pub use crate::types::Bolt11Invoice; + pub use cashu::types::InvoiceStatus; // UDL diff --git a/bindings/cashu-ffi/src/nuts/nut09/mod.rs b/bindings/cashu-ffi/src/nuts/nut09/mod.rs index 7aec20e9..d8e31e90 100644 --- a/bindings/cashu-ffi/src/nuts/nut09/mod.rs +++ b/bindings/cashu-ffi/src/nuts/nut09/mod.rs @@ -54,7 +54,7 @@ impl MintInfo { version: Option>, description: Option, description_long: Option, - contact: Vec>, + contact: Option>>, nuts: Vec, motd: Option, ) -> Self { diff --git a/bindings/cashu-ffi/src/types/proofs_status.rs b/bindings/cashu-ffi/src/types/proofs_status.rs new file mode 100644 index 00000000..13a48c16 --- /dev/null +++ b/bindings/cashu-ffi/src/types/proofs_status.rs @@ -0,0 +1,41 @@ +use std::{ops::Deref, sync::Arc}; + +use cashu::types::ProofsStatus as ProofsStatusSdk; + +use crate::MintProof; + +pub struct ProofsStatus { + inner: ProofsStatusSdk, +} + +impl ProofsStatus { + pub fn new(spendable: Vec>, spent: Vec>) -> Self { + Self { + inner: ProofsStatusSdk { + spendable: spendable + .iter() + .map(|p| p.as_ref().deref().clone()) + .collect(), + spent: spent.iter().map(|p| p.as_ref().deref().clone()).collect(), + }, + } + } + + pub fn spendable(&self) -> Vec> { + self.inner + .spendable + .clone() + .into_iter() + .map(|p| Arc::new(p.into())) + .collect() + } + + pub fn spent(&self) -> Vec> { + self.inner + .spent + .clone() + .into_iter() + .map(|p| Arc::new(p.into())) + .collect() + } +} diff --git a/bindings/cashu-sdk-ffi/README.md b/bindings/cashu-sdk-ffi/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/bindings/cashu-sdk-ffi/bindings-python/README.md b/bindings/cashu-sdk-ffi/bindings-python/README.md index e69de29b..08de3ed8 100644 --- a/bindings/cashu-sdk-ffi/bindings-python/README.md +++ b/bindings/cashu-sdk-ffi/bindings-python/README.md @@ -0,0 +1,50 @@ +Cashu Sdk Python bindings + + +**ALPHA** This library is in early development, the api will change. + +## Supported Nuts: + +Check: [https://github.com/thesimplekid/cashu-crab#implemented-nuts](https://github.com/thesimplekid/cashu-crab#implemented-nuts) + +## Build the package + +```shell +just python +``` + +## Getting Started + +For now this is not published as a package as it is still in early development. So you will have to build it as above. In the future this will be pulished and pip can be used to install. + +```python +from cashu_sdk import Wallet, Client, Amount + +client = Client("https://mutinynet-cashu.thesimplekid.space") + +mint_keys = client.get_keys() + +wallet = Wallet(client, mint_keys) + +mint_request = wallet.request_mint(Amount.from_sat(10)) + +print(mint_request.invoice()) + +print(mint_request.hash()) + +``` + + +## License + +Code is under the [BSD 3-Clause License](LICENSE) + +## Contribution + +All contributions welcome. + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed as above, without any additional terms or conditions. + +## Contact + +I can be contacted for comments or questions on nostr at _@thesimplekid.com (npub1qjgcmlpkeyl8mdkvp4s0xls4ytcux6my606tgfx9xttut907h0zs76lgjw) or via email tsk@thesimplekid.com. diff --git a/bindings/cashu-sdk-ffi/bindings-python/examples/test.py b/bindings/cashu-sdk-ffi/bindings-python/examples/test.py deleted file mode 100644 index c6e1ca9a..00000000 --- a/bindings/cashu-sdk-ffi/bindings-python/examples/test.py +++ /dev/null @@ -1,3 +0,0 @@ -import cashu_sdk; - -help(cashu_sdk) \ No newline at end of file diff --git a/bindings/cashu-sdk-ffi/bindings-python/examples/wallet.py b/bindings/cashu-sdk-ffi/bindings-python/examples/wallet.py new file mode 100644 index 00000000..c8d56781 --- /dev/null +++ b/bindings/cashu-sdk-ffi/bindings-python/examples/wallet.py @@ -0,0 +1,13 @@ +from cashu_sdk import Wallet, Client, Amount + +client = Client("https://mutinynet-cashu.thesimplekid.space") + +mint_keys = client.get_keys() + +wallet = Wallet(client, mint_keys) + +mint_request = wallet.request_mint(Amount.from_sat(10)) + +print(mint_request.invoice()) + +print(mint_request.hash()) diff --git a/bindings/cashu-sdk-ffi/src/cashu_sdk.udl b/bindings/cashu-sdk-ffi/src/cashu_sdk.udl index ba78f465..a4764e5c 100644 --- a/bindings/cashu-sdk-ffi/src/cashu_sdk.udl +++ b/bindings/cashu-sdk-ffi/src/cashu_sdk.udl @@ -216,7 +216,7 @@ interface MintVersion { }; interface MintInfo { - constructor(string? name, PublicKey? pubkey, MintVersion? version, string? description, string? description_long, sequence> contact, sequence nuts, string? motd); + constructor(string? name, PublicKey? pubkey, MintVersion? version, string? description, string? description_long, sequence>? contact, sequence nuts, string? motd); }; enum InvoiceStatus { @@ -226,6 +226,12 @@ enum InvoiceStatus { "InFlight" }; +interface ProofsStatus { + constructor(sequence spendable, sequence spent); + sequence spendable(); + sequence spent(); +}; + // Cashu Sdk @@ -272,7 +278,6 @@ interface Client { interface Wallet { constructor(Client client, Keys mint_keys); - // TODO: ProofStatus type // [Throws=CashuSdkError] // ProofsStatus check_proofs_spent(sequence proofs); [Throws=CashuSdkError] diff --git a/bindings/cashu-sdk-ffi/src/lib.rs b/bindings/cashu-sdk-ffi/src/lib.rs index a7a8b64e..d497714d 100644 --- a/bindings/cashu-sdk-ffi/src/lib.rs +++ b/bindings/cashu-sdk-ffi/src/lib.rs @@ -15,7 +15,7 @@ mod ffi { pub use crate::client::Client; pub use crate::error::CashuSdkError; - pub use crate::types::{Melted, SendProofs}; + pub use crate::types::{Melted, ProofsStatus, SendProofs}; pub use crate::wallet::Wallet; // UDL diff --git a/bindings/cashu-sdk-ffi/src/types/mod.rs b/bindings/cashu-sdk-ffi/src/types/mod.rs index cd6460fe..88836ac7 100644 --- a/bindings/cashu-sdk-ffi/src/types/mod.rs +++ b/bindings/cashu-sdk-ffi/src/types/mod.rs @@ -1,5 +1,7 @@ pub mod melted; +pub mod proofs_status; pub mod send_proofs; pub use melted::Melted; +pub use proofs_status::ProofsStatus; pub use send_proofs::SendProofs; diff --git a/bindings/cashu-sdk-ffi/src/types/proofs_status.rs b/bindings/cashu-sdk-ffi/src/types/proofs_status.rs new file mode 100644 index 00000000..ec542d5c --- /dev/null +++ b/bindings/cashu-sdk-ffi/src/types/proofs_status.rs @@ -0,0 +1,41 @@ +use std::{ops::Deref, sync::Arc}; + +use cashu_sdk::types::ProofsStatus as ProofsStatusSdk; + +use crate::MintProof; + +pub struct ProofsStatus { + inner: ProofsStatusSdk, +} + +impl ProofsStatus { + pub fn new(spendable: Vec>, spent: Vec>) -> Self { + Self { + inner: ProofsStatusSdk { + spendable: spendable + .iter() + .map(|p| p.as_ref().deref().clone()) + .collect(), + spent: spent.iter().map(|p| p.as_ref().deref().clone()).collect(), + }, + } + } + + pub fn spendable(&self) -> Vec> { + self.inner + .spendable + .clone() + .into_iter() + .map(|p| Arc::new(p.into())) + .collect() + } + + pub fn spent(&self) -> Vec> { + self.inner + .spent + .clone() + .into_iter() + .map(|p| Arc::new(p.into())) + .collect() + } +} diff --git a/crates/cashu/src/nuts/nut09.rs b/crates/cashu/src/nuts/nut09.rs index ca0c1bb9..0ed5f56d 100644 --- a/crates/cashu/src/nuts/nut09.rs +++ b/crates/cashu/src/nuts/nut09.rs @@ -58,8 +58,8 @@ pub struct MintInfo { #[serde(skip_serializing_if = "Option::is_none")] pub description_long: Option, /// contact methods to reach the mint operator - #[serde(skip_serializing_if = "Vec::is_empty")] - pub contact: Vec>, + #[serde(skip_serializing_if = "Option::is_none")] + pub contact: Option>>, /// shows which NUTs the mint supports #[serde(skip_serializing_if = "Vec::is_empty")] pub nuts: Vec,