nostr_sdk/client/
options.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 Options
6
7#[cfg(not(target_arch = "wasm32"))]
8use std::net::SocketAddr;
9#[cfg(all(feature = "tor", not(target_arch = "wasm32")))]
10use std::path::Path;
11use std::time::Duration;
12
13use nostr_relay_pool::prelude::*;
14
15#[allow(missing_docs)]
16#[deprecated(since = "0.43.0", note = "Use `ClientOptions` instead.")]
17pub type Options = ClientOptions;
18
19/// Options
20#[derive(Debug, Clone, Default)]
21pub struct ClientOptions {
22    pub(super) autoconnect: bool,
23    pub(super) gossip: bool,
24    #[cfg(not(target_arch = "wasm32"))]
25    pub(super) connection: Connection,
26    pub(super) relay_limits: RelayLimits,
27    pub(super) max_avg_latency: Option<Duration>,
28    pub(super) sleep_when_idle: SleepWhenIdle,
29    pub(super) verify_subscriptions: bool,
30    pub(super) ban_relay_on_mismatch: bool,
31    pub(super) pool: RelayPoolOptions,
32}
33
34impl ClientOptions {
35    /// Create new default options
36    #[inline]
37    pub fn new() -> Self {
38        Self::default()
39    }
40
41    /// Automatically start connection with relays (default: false)
42    ///
43    /// When set to `true`, there isn't the need of calling the connect methods.
44    #[inline]
45    pub fn autoconnect(mut self, val: bool) -> Self {
46        self.autoconnect = val;
47        self
48    }
49
50    /// Minimum POW difficulty for received events (default: 0)
51    #[deprecated(
52        since = "0.40.0",
53        note = "This no longer works, please use `AdmitPolicy` instead."
54    )]
55    pub fn min_pow(self, _difficulty: u8) -> Self {
56        self
57    }
58
59    /// REQ filters chunk size (default: 10)
60    #[deprecated(since = "0.39.0")]
61    pub fn req_filters_chunk_size(self, _size: u8) -> Self {
62        self
63    }
64
65    /// Auto authenticate to relays (default: true)
66    ///
67    /// <https://github.com/nostr-protocol/nips/blob/master/42.md>
68    #[inline]
69    pub fn automatic_authentication(mut self, enabled: bool) -> Self {
70        self.pool = self.pool.automatic_authentication(enabled);
71        self
72    }
73
74    /// Enable gossip model (default: false)
75    #[inline]
76    pub fn gossip(mut self, enable: bool) -> Self {
77        self.gossip = enable;
78        self
79    }
80
81    /// Connection mode and target
82    #[inline]
83    #[cfg(not(target_arch = "wasm32"))]
84    pub fn connection(mut self, connection: Connection) -> Self {
85        self.connection = connection;
86        self
87    }
88
89    /// Set relay limits
90    #[inline]
91    pub fn relay_limits(mut self, limits: RelayLimits) -> Self {
92        self.relay_limits = limits;
93        self
94    }
95
96    /// Set max latency (default: None)
97    ///
98    /// Relays with an avg. latency greater that this value will be skipped.
99    #[inline]
100    pub fn max_avg_latency(mut self, max: Duration) -> Self {
101        self.max_avg_latency = Some(max);
102        self
103    }
104
105    /// Set sleep when idle config
106    #[inline]
107    pub fn sleep_when_idle(mut self, config: SleepWhenIdle) -> Self {
108        self.sleep_when_idle = config;
109        self
110    }
111
112    /// Notification channel size (default: [`DEFAULT_NOTIFICATION_CHANNEL_SIZE`])
113    #[deprecated(since = "0.42.0", note = "Use `Options::pool` instead.")]
114    pub fn notification_channel_size(mut self, size: usize) -> Self {
115        self.pool = self.pool.notification_channel_size(size);
116        self
117    }
118
119    /// Verify that received events belong to a subscription and match the filter.
120    pub fn verify_subscriptions(mut self, enable: bool) -> Self {
121        self.verify_subscriptions = enable;
122        self
123    }
124
125    /// If true, ban a relay when it sends an event that doesn't match the subscription filter.
126    pub fn ban_relay_on_mismatch(mut self, ban_relay: bool) -> Self {
127        self.ban_relay_on_mismatch = ban_relay;
128        self
129    }
130
131    /// Set relay pool options
132    #[inline]
133    pub fn pool(mut self, opts: RelayPoolOptions) -> Self {
134        self.pool = opts;
135        self
136    }
137}
138
139/// Put relays to sleep when idle.
140#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
141pub enum SleepWhenIdle {
142    /// Disabled
143    #[default]
144    Disabled,
145    /// Enabled for all relays
146    Enabled {
147        /// Idle timeout
148        ///
149        /// After how much time of inactivity put the relay to sleep.
150        timeout: Duration,
151    },
152}
153
154/// Connection target
155#[cfg(not(target_arch = "wasm32"))]
156#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
157pub enum ConnectionTarget {
158    /// All relays
159    #[default]
160    All,
161    /// Only `.onion` relays
162    Onion,
163}
164
165/// Connection
166#[cfg(not(target_arch = "wasm32"))]
167#[derive(Debug, Clone, PartialEq, Eq, Hash)]
168pub struct Connection {
169    /// Mode
170    pub mode: ConnectionMode,
171    /// Target
172    pub target: ConnectionTarget,
173}
174
175#[allow(clippy::derivable_impls)]
176#[cfg(not(target_arch = "wasm32"))]
177impl Default for Connection {
178    fn default() -> Self {
179        #[cfg(all(feature = "tor", not(target_os = "android"), not(target_os = "ios")))]
180        {
181            Self {
182                mode: ConnectionMode::tor(),
183                target: ConnectionTarget::Onion,
184            }
185        }
186
187        #[cfg(any(
188            not(feature = "tor"),
189            all(feature = "tor", any(target_os = "android", target_os = "ios")),
190        ))]
191        Self {
192            mode: ConnectionMode::default(),
193            target: ConnectionTarget::default(),
194        }
195    }
196}
197
198#[cfg(not(target_arch = "wasm32"))]
199impl Connection {
200    /// New default connection config
201    #[inline]
202    pub fn new() -> Self {
203        Self {
204            mode: ConnectionMode::default(),
205            target: ConnectionTarget::default(),
206        }
207    }
208
209    /// Set connection mode (default: direct)
210    #[inline]
211    pub fn mode(mut self, mode: ConnectionMode) -> Self {
212        self.mode = mode;
213        self
214    }
215
216    /// Set connection target (default: all)
217    #[inline]
218    pub fn target(mut self, target: ConnectionTarget) -> Self {
219        self.target = target;
220        self
221    }
222
223    /// Set direct connection
224    #[inline]
225    pub fn direct(mut self) -> Self {
226        self.mode = ConnectionMode::direct();
227        self
228    }
229
230    /// Set proxy
231    #[inline]
232    pub fn proxy(mut self, addr: SocketAddr) -> Self {
233        self.mode = ConnectionMode::proxy(addr);
234        self
235    }
236
237    /// Use embedded tor client
238    #[inline]
239    #[cfg(feature = "tor")]
240    pub fn embedded_tor(mut self) -> Self {
241        self.mode = ConnectionMode::tor();
242        self
243    }
244
245    /// Use embedded tor client
246    ///
247    /// Specify a path where to store data
248    #[inline]
249    #[cfg(feature = "tor")]
250    pub fn embedded_tor_with_path<P>(mut self, path: P) -> Self
251    where
252        P: AsRef<Path>,
253    {
254        self.mode = ConnectionMode::tor_with_path(path);
255        self
256    }
257}