use alloc::borrow::Cow;
use alloc::string::String;
use alloc::sync::Arc;
use core::any::Any;
use core::fmt::{self, Debug};
use crate::util::BoxedFuture;
use crate::{Event, PublicKey, UnsignedEvent};
#[derive(Debug, PartialEq, Eq)]
pub struct SignerError(String);
#[cfg(feature = "std")]
impl std::error::Error for SignerError {}
impl fmt::Display for SignerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0.as_str())
}
}
impl SignerError {
#[inline]
#[cfg(feature = "std")]
pub fn backend<E>(error: E) -> Self
where
E: std::error::Error,
{
Self(error.to_string())
}
#[inline]
#[cfg(not(feature = "std"))]
pub fn backend<E>(error: E) -> Self
where
E: Into<String>,
{
Self(error.into())
}
}
impl<S> From<S> for SignerError
where
S: Into<String>,
{
fn from(error: S) -> Self {
Self(error.into())
}
}
#[doc(hidden)]
pub trait IntoNostrSigner {
fn into_nostr_signer(self) -> Arc<dyn NostrSigner>;
}
impl<T> IntoNostrSigner for T
where
T: NostrSigner + 'static,
{
fn into_nostr_signer(self) -> Arc<dyn NostrSigner> {
Arc::new(self)
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SignerBackend<'a> {
Keys,
BrowserExtension,
NostrConnect,
Custom(Cow<'a, str>),
}
pub trait NostrSigner: Any + Debug + Send + Sync {
fn backend(&self) -> SignerBackend;
fn get_public_key(&self) -> BoxedFuture<Result<PublicKey, SignerError>>;
fn sign_event(&self, unsigned: UnsignedEvent) -> BoxedFuture<Result<Event, SignerError>>;
fn nip04_encrypt<'a>(
&'a self,
public_key: &'a PublicKey,
content: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>>;
fn nip04_decrypt<'a>(
&'a self,
public_key: &'a PublicKey,
encrypted_content: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>>;
fn nip44_encrypt<'a>(
&'a self,
public_key: &'a PublicKey,
content: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>>;
fn nip44_decrypt<'a>(
&'a self,
public_key: &'a PublicKey,
payload: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>>;
}
impl NostrSigner for Arc<dyn NostrSigner> {
#[inline]
fn backend(&self) -> SignerBackend {
self.as_ref().backend()
}
#[inline]
fn get_public_key(&self) -> BoxedFuture<Result<PublicKey, SignerError>> {
self.as_ref().get_public_key()
}
#[inline]
fn sign_event(&self, unsigned: UnsignedEvent) -> BoxedFuture<Result<Event, SignerError>> {
self.as_ref().sign_event(unsigned)
}
#[inline]
fn nip04_encrypt<'a>(
&'a self,
public_key: &'a PublicKey,
content: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>> {
self.as_ref().nip04_encrypt(public_key, content)
}
#[inline]
fn nip04_decrypt<'a>(
&'a self,
public_key: &'a PublicKey,
encrypted_content: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>> {
self.as_ref().nip04_decrypt(public_key, encrypted_content)
}
#[inline]
fn nip44_encrypt<'a>(
&'a self,
public_key: &'a PublicKey,
content: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>> {
self.as_ref().nip44_encrypt(public_key, content)
}
#[inline]
fn nip44_decrypt<'a>(
&'a self,
public_key: &'a PublicKey,
payload: &'a str,
) -> BoxedFuture<'a, Result<String, SignerError>> {
self.as_ref().nip44_decrypt(public_key, payload)
}
}