nostr_rust/
lib.rs

1use events::{Event, EventPrepare};
2use secp256k1::{PublicKey, SecretKey};
3use std::str::FromStr;
4use utils::get_timestamp;
5
6pub mod bech32;
7pub mod events;
8pub mod keys;
9pub mod nips;
10pub mod nostr_client;
11pub mod req;
12pub mod utils;
13pub mod websocket;
14
15pub const DEFAULT_HASHTAG: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
16
17pub type Message = tungstenite::Message;
18
19/// Nostr Identity with secret and public keys
20pub struct Identity {
21    pub secret_key: SecretKey,
22    pub public_key: PublicKey,
23    pub public_key_str: String,
24    pub address: String,
25}
26
27impl Identity {
28    /// Make event and return it
29    ///
30    /// # Example
31    /// ```rust
32    /// use nostr_rust::{nostr_client::Client, Identity};
33    /// use std::str::FromStr;
34    ///
35    ///
36    /// #[cfg(feature = "async")]
37    /// async fn test_make_event() {
38    ///    let mut client = Client::new(vec![env!("RELAY_URL")]).await.unwrap();
39    ///    let identity = Identity::from_str(env!("SECRET_KEY")).unwrap();
40    ///    let event = identity.make_event(1, "Hello Nostr!", &vec![], 0);
41    ///
42    ///    assert_eq!(event.kind, 1);
43    ///    assert_eq!(event.content, "Hello Nostr!");
44    ///    assert_eq!(event.tags.len(), 0);
45    /// }
46    ///
47    /// #[cfg(not(feature = "async"))]
48    /// fn test_make_event() {
49    ///    let mut client = Client::new(vec![env!("RELAY_URL")]).unwrap();
50    ///    let identity = Identity::from_str(env!("SECRET_KEY")).unwrap();
51    ///    let event = identity.make_event(1, "Hello Nostr!", &vec![], 0);
52    ///
53    ///    assert_eq!(event.kind, 1);
54    ///    assert_eq!(event.content, "Hello Nostr!");
55    ///    assert_eq!(event.tags.len(), 0);
56    /// }
57    ///
58    /// #[cfg(feature = "async")]
59    /// tokio::runtime::Runtime::new().unwrap().block_on(test_make_event());
60    ///
61    /// #[cfg(not(feature = "async"))]
62    /// test_make_event();
63    /// ```
64    pub fn make_event(
65        &self,
66        kind: u16,
67        content: &str,
68        tags: &[Vec<String>],
69        difficulty_target: u16,
70    ) -> Event {
71        EventPrepare {
72            pub_key: self.public_key_str.clone(),
73            created_at: get_timestamp(),
74            kind,
75            tags: tags.to_vec(),
76            content: content.to_string(),
77        }
78        .to_event(self, difficulty_target)
79    }
80}
81
82impl FromStr for Identity {
83    type Err = String;
84
85    /// Create an Identity from a secret key as a hex string
86    /// # Example
87    /// ```
88    /// use nostr_rust::Identity;
89    /// use std::str::FromStr;
90    ///
91    /// // Working format
92    /// let identity = Identity::from_str(env!("SECRET_KEY"));
93    /// assert!(identity.is_ok());
94    ///
95    /// // Invalid format
96    /// let identity = Identity::from_str("aeaeaeaeae");
97    /// assert!(identity.is_err());
98    /// ```
99    fn from_str(secret_key: &str) -> Result<Self, Self::Err> {
100        let secret_key = keys::secret_key_from_str(&{
101            if secret_key.starts_with("nsec") {
102                crate::bech32::from_hb_to_hex(crate::bech32::ToBech32Kind::SecretKey, secret_key)
103                    .unwrap()
104            } else {
105                secret_key.to_string()
106            }
107        })?;
108        let public_key = keys::get_public_key_from_secret(&secret_key);
109        let address = keys::get_str_keys_from_secret(&secret_key).1;
110
111        Ok(Self {
112            secret_key,
113            public_key,
114            public_key_str: address.to_string(),
115            address,
116        })
117    }
118}