1#![forbid(unsafe_code)]
8#![warn(missing_docs)]
9#![warn(rustdoc::bare_urls)]
10#![cfg_attr(docsrs, feature(doc_auto_cfg))]
11#![doc = include_str!("../README.md")]
12
13use nrc_mls_storage::NostrMlsStorageProvider;
14use openmls::prelude::*;
15use openmls_rust_crypto::RustCrypto;
16
17mod constant;
18pub mod error;
19pub mod extension;
20pub mod groups;
21pub mod key_packages;
22pub mod messages;
23pub mod prelude;
24#[cfg(test)]
25pub mod test_util;
26mod util;
27pub mod welcomes;
28
29use self::constant::{DEFAULT_CIPHERSUITE, REQUIRED_EXTENSIONS};
30pub use self::error::Error;
31
32#[derive(Debug)]
42pub struct NostrMls<Storage>
43where
44 Storage: NostrMlsStorageProvider,
45{
46 pub ciphersuite: Ciphersuite,
48 pub extensions: Vec<ExtensionType>,
50 pub provider: NostrMlsProvider<Storage>,
52}
53
54#[derive(Debug)]
61pub struct NostrMlsProvider<Storage>
62where
63 Storage: NostrMlsStorageProvider,
64{
65 crypto: RustCrypto,
66 storage: Storage,
67}
68
69impl<Storage> OpenMlsProvider for NostrMlsProvider<Storage>
70where
71 Storage: NostrMlsStorageProvider,
72{
73 type CryptoProvider = RustCrypto;
74 type RandProvider = RustCrypto;
75 type StorageProvider = Storage::OpenMlsStorageProvider;
76
77 fn storage(&self) -> &Self::StorageProvider {
78 self.storage.openmls_storage()
79 }
80
81 fn crypto(&self) -> &Self::CryptoProvider {
82 &self.crypto
83 }
84
85 fn rand(&self) -> &Self::RandProvider {
86 &self.crypto
87 }
88}
89
90impl<Storage> NostrMls<Storage>
91where
92 Storage: NostrMlsStorageProvider,
93{
94 pub fn new(storage: Storage) -> Self {
96 Self {
97 ciphersuite: DEFAULT_CIPHERSUITE,
98 extensions: REQUIRED_EXTENSIONS.to_vec(),
99 provider: NostrMlsProvider {
100 crypto: RustCrypto::default(),
101 storage,
102 },
103 }
104 }
105
106 #[inline]
108 pub(crate) fn capabilities(&self) -> Capabilities {
109 Capabilities::new(
110 None,
111 Some(&[self.ciphersuite]),
112 Some(&self.extensions),
113 None,
114 None,
115 )
116 }
117
118 #[inline]
120 pub(crate) fn required_capabilities_extension(&self) -> Extension {
121 Extension::RequiredCapabilities(RequiredCapabilitiesExtension::new(
122 &self.extensions,
123 &[],
124 &[],
125 ))
126 }
127
128 pub(crate) fn ciphersuite_value(&self) -> u16 {
130 self.ciphersuite.into()
131 }
132
133 pub(crate) fn extensions_value(&self) -> String {
135 self.extensions
136 .iter()
137 .map(|e| format!("{:?}", e))
138 .collect::<Vec<String>>()
139 .join(",")
140 }
141
142 pub(crate) fn storage(&self) -> &Storage {
144 &self.provider.storage
145 }
146}
147
148#[cfg(test)]
150pub mod tests {
151 use nostr_mls_memory_storage::NostrMlsMemoryStorage;
152
153 use super::*;
154
155 pub fn create_test_nostr_mls() -> NostrMls<NostrMlsMemoryStorage> {
157 NostrMls::new(NostrMlsMemoryStorage::default())
158 }
159}