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}