cdk_npubcash/lib.rs
1//! # NpubCash SDK
2//!
3//! Rust client SDK for the NpubCash v2 API.
4//!
5//! ## Features
6//!
7//! - HTTP client for fetching quotes with auto-pagination
8//! - NIP-98 and JWT authentication
9//! - User settings management
10//!
11//! ## Quick Start
12//!
13//! ```no_run
14//! use std::sync::Arc;
15//!
16//! use cdk_npubcash::{JwtAuthProvider, NpubCashClient};
17//! use nostr_sdk::Keys;
18//!
19//! #[tokio::main]
20//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
21//! // Create authentication provider with Nostr keys
22//! let base_url = "https://npubx.cash".to_string();
23//! let keys = Keys::generate();
24//! let auth_provider = Arc::new(JwtAuthProvider::new(base_url.clone(), keys));
25//!
26//! // Create the NpubCash client
27//! let client = NpubCashClient::new(base_url, auth_provider);
28//!
29//! // Fetch all quotes
30//! let quotes = client.get_quotes(None).await?;
31//! println!("Found {} quotes", quotes.len());
32//!
33//! // Fetch quotes since a specific timestamp
34//! let recent_quotes = client.get_quotes(Some(1234567890)).await?;
35//! println!("Found {} recent quotes", recent_quotes.len());
36//!
37//! // Update mint URL setting
38//! client.set_mint_url("https://example-mint.tld").await?;
39//!
40//! Ok(())
41//! }
42//! ```
43//!
44//! ## Authentication
45//!
46//! The SDK uses NIP-98 HTTP authentication for initial requests and JWT tokens
47//! for subsequent requests. The [`JwtAuthProvider`] handles this automatically,
48//! including token caching and refresh.
49//!
50//! ## Fetching Quotes
51//!
52//! ```no_run
53//! # use cdk_npubcash::{NpubCashClient, JwtAuthProvider};
54//! # use nostr_sdk::Keys;
55//! # use std::sync::Arc;
56//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
57//! # let base_url = "https://npubx.cash".to_string();
58//! # let keys = Keys::generate();
59//! # let auth_provider = Arc::new(JwtAuthProvider::new(base_url.clone(), keys));
60//! # let client = NpubCashClient::new(base_url, auth_provider);
61//! // Fetch all quotes
62//! let all_quotes = client.get_quotes(None).await?;
63//!
64//! // Fetch quotes since a specific timestamp
65//! let recent_quotes = client.get_quotes(Some(1234567890)).await?;
66//! # Ok(())
67//! # }
68//! ```
69//!
70//! ## Managing Settings
71//!
72//! ```no_run
73//! # use cdk_npubcash::{NpubCashClient, JwtAuthProvider};
74//! # use nostr_sdk::Keys;
75//! # use std::sync::Arc;
76//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
77//! # let base_url = "https://npubx.cash".to_string();
78//! # let keys = Keys::generate();
79//! # let auth_provider = Arc::new(JwtAuthProvider::new(base_url.clone(), keys));
80//! # let client = NpubCashClient::new(base_url, auth_provider);
81//! // Set mint URL
82//! let response = client.set_mint_url("https://my-mint.com").await?;
83//! println!("Mint URL: {:?}", response.data.user.mint_url);
84//! println!("Lock quote: {}", response.data.user.lock_quote);
85//! # Ok(())
86//! # }
87//! ```
88//!
89//! **Note:** Quotes are always locked by default on the NPubCash server for security.
90
91#![warn(missing_docs)]
92#![allow(clippy::doc_markdown)]
93
94pub mod auth;
95pub mod client;
96pub mod error;
97pub mod types;
98
99// Re-export main types for convenient access
100pub use auth::JwtAuthProvider;
101pub use client::NpubCashClient;
102pub use error::{Error, Result};
103pub use types::{
104 Metadata, Nip98Data, Nip98Response, Quote, QuotesData, QuotesResponse, UserData, UserResponse,
105};
106
107/// Extract authentication URL (scheme + host + path, no query params)
108///
109/// # Arguments
110///
111/// * `url` - The full URL to parse
112///
113/// # Errors
114///
115/// Returns an error if the URL is invalid or missing required components
116pub(crate) fn extract_auth_url(url: &str) -> Result<String> {
117 let parsed_url = url::Url::parse(url)?;
118 let host = parsed_url
119 .host_str()
120 .ok_or_else(|| Error::Custom("Invalid URL: missing host".to_string()))?;
121
122 Ok(format!(
123 "{}://{}{}",
124 parsed_url.scheme(),
125 host,
126 parsed_url.path()
127 ))
128}