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