1use crate::{
2 ContentEncryptionAlgorithm, DelegationConditions, EncryptedPrivateKey, Error, Event, EventKind,
3 Id, KeySecurity, KeySigner, Metadata, ParsedTag, PreEvent, PrivateKey, PublicKey, Rumor,
4 Signature, Tag, Unixtime,
5};
6use async_trait::async_trait;
7use rand::Rng;
8use rand_core::OsRng;
9use std::fmt;
10use std::sync::atomic::{AtomicBool, AtomicU64, AtomicU8, Ordering};
11use std::sync::mpsc::Sender;
12use std::sync::Arc;
13use std::thread;
14use std::thread::JoinHandle;
15
16#[async_trait]
18pub trait Signer: fmt::Debug + Send + Sync {
19 fn public_key(&self) -> PublicKey;
21
22 fn encrypted_private_key(&self) -> Option<EncryptedPrivateKey>;
24
25 async fn sign_event(&self, input: PreEvent) -> Result<Event, Error>;
27
28 async fn encrypt(
56 &self,
57 other: &PublicKey,
58 plaintext: &str,
59 algo: ContentEncryptionAlgorithm,
60 ) -> Result<String, Error>;
61
62 async fn decrypt(&self, other: &PublicKey, ciphertext: &str) -> Result<String, Error>;
64
65 fn key_security(&self) -> Result<KeySecurity, Error>;
67
68 async fn giftwrap(&self, input: PreEvent, pubkey: PublicKey) -> Result<Event, Error> {
70 let sender_pubkey = input.pubkey;
71
72 if sender_pubkey != self.public_key() {
74 return Err(Error::InvalidPrivateKey);
75 }
76
77 let seal_backdate = Unixtime(
78 input.created_at.0
79 - OsRng.sample(rand::distributions::Uniform::new(30, 60 * 60 * 24 * 2)),
80 );
81 let giftwrap_backdate = Unixtime(
82 input.created_at.0
83 - OsRng.sample(rand::distributions::Uniform::new(30, 60 * 60 * 24 * 2)),
84 );
85
86 let seal = {
87 let rumor = Rumor::new(input)?;
88 let rumor_json = serde_json::to_string(&rumor)?;
89 let encrypted_rumor_json = self
90 .encrypt(&pubkey, &rumor_json, ContentEncryptionAlgorithm::Nip44v2)
91 .await?;
92
93 let pre_seal = PreEvent {
94 pubkey: sender_pubkey,
95 created_at: seal_backdate,
96 kind: EventKind::Seal,
97 content: encrypted_rumor_json,
98 tags: vec![],
99 };
100
101 self.sign_event(pre_seal).await?
102 };
103
104 let random_signer = {
106 let random_private_key = PrivateKey::generate();
107 KeySigner::from_private_key(random_private_key, "", 1)
108 }?;
109
110 let seal_json = serde_json::to_string(&seal)?;
111 let encrypted_seal_json = random_signer
112 .encrypt(&pubkey, &seal_json, ContentEncryptionAlgorithm::Nip44v2)
113 .await?;
114
115 let pre_giftwrap = PreEvent {
116 pubkey: random_signer.public_key(),
117 created_at: giftwrap_backdate,
118 kind: EventKind::GiftWrap,
119 content: encrypted_seal_json,
120 tags: vec![ParsedTag::Pubkey {
121 pubkey,
122 recommended_relay_url: None,
123 petname: None,
124 }
125 .into_tag()],
126 };
127
128 random_signer.sign_event(pre_giftwrap).await
129 }
130
131 async fn create_metadata_event(
133 &self,
134 mut input: PreEvent,
135 metadata: Metadata,
136 ) -> Result<Event, Error> {
137 input.kind = EventKind::Metadata;
138 input.content = serde_json::to_string(&metadata)?;
139 self.sign_event(input).await
140 }
141
142 async fn create_zap_request_event(
145 &self,
146 recipient_pubkey: PublicKey,
147 zapped_event: Option<Id>,
148 millisatoshis: u64,
149 relays: Vec<String>,
150 content: String,
151 ) -> Result<Event, Error> {
152 let mut relays_tag = Tag::new(&["relays"]);
153 relays_tag.push_values(relays);
154
155 let mut pre_event = PreEvent {
156 pubkey: self.public_key(),
157 created_at: Unixtime::now(),
158 kind: EventKind::ZapRequest,
159 tags: vec![
160 ParsedTag::Pubkey {
161 pubkey: recipient_pubkey,
162 recommended_relay_url: None,
163 petname: None,
164 }
165 .into_tag(),
166 relays_tag,
167 Tag::new(&["amount", &format!("{millisatoshis}")]),
168 ],
169 content,
170 };
171
172 if let Some(ze) = zapped_event {
173 pre_event.tags.push(
174 ParsedTag::Event {
175 id: ze,
176 recommended_relay_url: None,
177 marker: None,
178 author_pubkey: None,
179 }
180 .into_tag(),
181 );
182 }
183
184 self.sign_event(pre_event).await
185 }
186
187 async fn decrypt_event_contents(&self, event: &Event) -> Result<String, Error> {
189 if !event.kind.contents_are_encrypted() {
190 return Err(Error::WrongEventKind);
191 }
192
193 let pubkey = if event.pubkey == self.public_key() {
194 event
196 .people()
197 .iter()
198 .filter_map(|(pk, _, _)| if *pk != event.pubkey { Some(*pk) } else { None })
199 .nth(0)
200 .unwrap_or(event.pubkey) } else {
202 event.pubkey
203 };
204
205 self.decrypt(&pubkey, &event.content).await
206 }
207
208 async fn unwrap_giftwrap(&self, event: &Event) -> Result<Rumor, Error> {
210 if event.kind != EventKind::GiftWrap {
211 return Err(Error::WrongEventKind);
212 }
213
214 let mut tagged = false;
216 for t in event.tags.iter() {
217 if let Ok(ParsedTag::Pubkey { pubkey, .. }) = t.parse() {
218 if pubkey == self.public_key() {
219 tagged = true;
220 }
221 }
222 }
223 if !tagged {
224 return Err(Error::InvalidRecipient);
225 }
226
227 let content = self.decrypt(&event.pubkey, &event.content).await?;
229
230 let seal: Event = serde_json::from_str(&content)?;
232
233 if seal.kind != EventKind::Seal {
235 return Err(Error::WrongEventKind);
236 }
237
238 seal.verify(None)?;
240
241 let author = seal.pubkey;
243
244 let content = self.decrypt(&seal.pubkey, &seal.content).await?;
246
247 let rumor: Rumor = serde_json::from_str(&content)?;
249
250 if rumor.pubkey != author {
252 return Err(Error::InvalidPublicKey);
253 }
254
255 Ok(rumor)
257 }
258}
259
260#[async_trait]
266pub trait SignerExt: Signer {
267 async fn sign_id(&self, id: Id) -> Result<Signature, Error>;
269
270 async fn sign(&self, message: &[u8]) -> Result<Signature, Error>;
272
273 async fn nip44_conversation_key(&self, other: &PublicKey) -> Result<[u8; 32], Error>;
275
276 async fn generate_delegation_signature(
278 &self,
279 delegated_pubkey: PublicKey,
280 delegation_conditions: &DelegationConditions,
281 ) -> Result<Signature, Error> {
282 let input = format!(
283 "nostr:delegation:{}:{}",
284 delegated_pubkey.as_hex_string(),
285 delegation_conditions.as_string()
286 );
287
288 self.sign(input.as_bytes()).await
289 }
290
291 fn verify_delegation_signature(
293 &self,
294 delegated_pubkey: PublicKey,
295 delegation_conditions: &DelegationConditions,
296 signature: &Signature,
297 ) -> Result<(), Error> {
298 let input = format!(
299 "nostr:delegation:{}:{}",
300 delegated_pubkey.as_hex_string(),
301 delegation_conditions.as_string()
302 );
303
304 self.public_key().verify(input.as_bytes(), signature)
305 }
306
307 async fn sign_event_with_pow(
309 &self,
310 mut input: PreEvent,
311 zero_bits: u8,
312 work_sender: Option<Sender<u8>>,
313 ) -> Result<Event, Error> {
314 let target = format!("{zero_bits}");
315
316 if input.pubkey != self.public_key() {
318 return Err(Error::InvalidPrivateKey);
319 }
320
321 input.tags.retain(|t| t.tagname() != "nonce");
323
324 input.tags.push(Tag::new(&["nonce", "0", &target]));
326 let index = input.tags.len() - 1;
327
328 let cores = num_cpus::get();
329
330 let quitting = Arc::new(AtomicBool::new(false));
331 let nonce = Arc::new(AtomicU64::new(0)); let best_work = Arc::new(AtomicU8::new(0));
333
334 let mut join_handles: Vec<JoinHandle<_>> = Vec::with_capacity(cores);
335
336 for core in 0..cores {
337 let mut attempt: u64 = core as u64 * (u64::MAX / cores as u64);
338 let mut input = input.clone();
339 let quitting = quitting.clone();
340 let nonce = nonce.clone();
341 let best_work = best_work.clone();
342 let work_sender = work_sender.clone();
343 let join_handle = thread::spawn(move || {
344 loop {
345 let _ = thread_priority::set_current_thread_priority(
347 thread_priority::ThreadPriority::Min,
348 );
349
350 if quitting.load(Ordering::Relaxed) {
351 break;
352 }
353
354 input.tags[index].set_index(1, format!("{attempt}"));
355
356 let Id(id) = input.hash().unwrap();
357
358 let leading_zeroes = crate::get_leading_zero_bits(&id);
359 if leading_zeroes >= zero_bits {
360 nonce.store(attempt, Ordering::Relaxed);
361 quitting.store(true, Ordering::Relaxed);
362 if let Some(sender) = work_sender.clone() {
363 sender.send(leading_zeroes).unwrap();
364 }
365 break;
366 } else if leading_zeroes > best_work.load(Ordering::Relaxed) {
367 best_work.store(leading_zeroes, Ordering::Relaxed);
368 if let Some(sender) = work_sender.clone() {
369 sender.send(leading_zeroes).unwrap();
370 }
371 }
372
373 attempt += 1;
374
375 }
377 });
378 join_handles.push(join_handle);
379 }
380
381 for joinhandle in join_handles {
382 let _ = joinhandle.join();
383 }
384
385 input.tags[index].set_index(1, format!("{}", nonce.load(Ordering::Relaxed)));
387 let id = input.hash().unwrap();
388
389 let signature = self.sign_id(id).await?;
391
392 Ok(Event {
393 id,
394 pubkey: input.pubkey,
395 created_at: input.created_at,
396 kind: input.kind,
397 tags: input.tags,
398 content: input.content,
399 sig: signature,
400 })
401 }
402}
403
404pub trait LockableSigner: Signer {
406 fn is_locked(&self) -> bool;
408
409 fn unlock(&self, password: &str) -> Result<(), Error>;
411
412 fn lock(&self);
414
415 fn change_passphrase(&self, old: &str, new: &str, log_n: u8) -> Result<(), Error>;
417
418 fn upgrade(&self, pass: &str, log_n: u8) -> Result<(), Error>;
420}
421
422#[async_trait]
425pub trait ExportableSigner: Signer {
426 async fn export_private_key_in_hex(
434 &self,
435 pass: &str,
436 log_n: u8,
437 ) -> Result<(String, bool), Error>;
438
439 async fn export_private_key_in_bech32(
447 &self,
448 pass: &str,
449 log_n: u8,
450 ) -> Result<(String, bool), Error>;
451}
452
453#[async_trait]
456pub trait MutExportableSigner: Signer {
457 async fn export_private_key_in_hex(
465 &mut self,
466 pass: &str,
467 log_n: u8,
468 ) -> Result<(String, bool), Error>;
469
470 async fn export_private_key_in_bech32(
478 &mut self,
479 pass: &str,
480 log_n: u8,
481 ) -> Result<(String, bool), Error>;
482}