nostr_sdk/client/
builder.rs

1// Copyright (c) 2022-2023 Yuki Kishimoto
2// Copyright (c) 2023-2025 Rust Nostr Developers
3// Distributed under the MIT software license
4
5//! Client builder
6
7use std::sync::Arc;
8
9use nostr::signer::{IntoNostrSigner, NostrSigner};
10use nostr_database::memory::MemoryDatabase;
11use nostr_database::{IntoNostrDatabase, NostrDatabase};
12use nostr_gossip::{IntoNostrGossip, NostrGossip};
13use nostr_relay_pool::monitor::Monitor;
14use nostr_relay_pool::policy::AdmitPolicy;
15use nostr_relay_pool::transport::websocket::{
16    DefaultWebsocketTransport, IntoWebSocketTransport, WebSocketTransport,
17};
18
19use crate::client::options::ClientOptions;
20use crate::client::Client;
21
22/// Client builder
23#[derive(Debug, Clone)]
24pub struct ClientBuilder {
25    /// Nostr Signer
26    pub signer: Option<Arc<dyn NostrSigner>>,
27    /// WebSocket transport
28    pub websocket_transport: Arc<dyn WebSocketTransport>,
29    /// Admission policy
30    pub admit_policy: Option<Arc<dyn AdmitPolicy>>,
31    /// Database
32    pub database: Arc<dyn NostrDatabase>,
33    /// Gossip
34    pub gossip: Option<Arc<dyn NostrGossip>>,
35    /// Relay monitor
36    pub monitor: Option<Monitor>,
37    /// Client options
38    pub opts: ClientOptions,
39}
40
41impl Default for ClientBuilder {
42    fn default() -> Self {
43        Self {
44            signer: None,
45            websocket_transport: Arc::new(DefaultWebsocketTransport),
46            admit_policy: None,
47            database: Arc::new(MemoryDatabase::default()),
48            gossip: None,
49            monitor: None,
50            opts: ClientOptions::default(),
51        }
52    }
53}
54
55impl ClientBuilder {
56    /// New default client builder
57    #[inline]
58    pub fn new() -> Self {
59        Self::default()
60    }
61
62    /// Set signer
63    ///
64    /// # Example
65    /// ```rust,no_run
66    /// use nostr_sdk::prelude::*;
67    ///
68    /// // Signer with private keys
69    /// let keys = Keys::generate();
70    /// let client = ClientBuilder::new().signer(keys).build();
71    /// ```
72    #[inline]
73    pub fn signer<T>(mut self, signer: T) -> Self
74    where
75        T: IntoNostrSigner,
76    {
77        self.signer = Some(signer.into_nostr_signer());
78        self
79    }
80
81    /// Set custom WebSocket transport
82    ///
83    /// By default [`DefaultWebsocketTransport`] is used.
84    #[inline]
85    pub fn websocket_transport<T>(mut self, transport: T) -> Self
86    where
87        T: IntoWebSocketTransport,
88    {
89        self.websocket_transport = transport.into_transport();
90        self
91    }
92
93    /// Set an admission policy
94    #[inline]
95    pub fn admit_policy<T>(mut self, policy: T) -> Self
96    where
97        T: AdmitPolicy + 'static,
98    {
99        self.admit_policy = Some(Arc::new(policy));
100        self
101    }
102
103    /// Set database
104    #[inline]
105    pub fn database<D>(mut self, database: D) -> Self
106    where
107        D: IntoNostrDatabase,
108    {
109        self.database = database.into_nostr_database();
110        self
111    }
112
113    /// Set a gossip database
114    #[inline]
115    pub fn gossip<T>(mut self, gossip: T) -> Self
116    where
117        T: IntoNostrGossip,
118    {
119        self.gossip = Some(gossip.into_nostr_gossip());
120        self
121    }
122
123    /// Set monitor
124    #[inline]
125    pub fn monitor(mut self, monitor: Monitor) -> Self {
126        self.monitor = Some(monitor);
127        self
128    }
129
130    /// Set opts
131    #[inline]
132    pub fn opts(mut self, opts: ClientOptions) -> Self {
133        self.opts = opts;
134        self
135    }
136
137    /// Build [`Client`]
138    #[inline]
139    pub fn build(self) -> Client {
140        Client::from_builder(self)
141    }
142}