nostr_types/types/
signature.rs1use crate::{Error, Event};
2use derive_more::{AsMut, AsRef, Deref, Display, From, FromStr, Into};
3use serde::{Deserialize, Serialize};
4#[cfg(feature = "speedy")]
5use speedy::{Context, Readable, Reader, Writable, Writer};
6
7#[derive(
9 AsMut, AsRef, Clone, Copy, Debug, Deref, Eq, From, Into, PartialEq, Serialize, Deserialize,
10)]
11pub struct Signature(pub secp256k1::schnorr::Signature);
12
13impl Signature {
14 pub fn as_hex_string(&self) -> String {
16 hex::encode(self.0.as_ref())
17 }
18
19 pub fn try_from_hex_string(v: &str) -> Result<Signature, Error> {
21 let vec: Vec<u8> = hex::decode(v)?;
22 Ok(Signature(secp256k1::schnorr::Signature::from_slice(&vec)?))
23 }
24
25 pub fn zeroes() -> Signature {
27 Signature(secp256k1::schnorr::Signature::from_slice(&[0; 64]).unwrap())
28 }
29
30 #[allow(dead_code)]
32 pub(crate) async fn mock() -> Signature {
33 let event = Event::mock().await;
34 event.sig
35 }
36}
37
38#[cfg(feature = "speedy")]
39impl<'a, C: Context> Readable<'a, C> for Signature {
40 #[inline]
41 fn read_from<R: Reader<'a, C>>(reader: &mut R) -> Result<Self, C::Error> {
42 let bytes: Vec<u8> = reader.read_vec(64)?;
43 let sig =
44 secp256k1::schnorr::Signature::from_slice(&bytes[..]).map_err(speedy::Error::custom)?;
45 Ok(Signature(sig))
46 }
47
48 #[inline]
49 fn minimum_bytes_needed() -> usize {
50 64
51 }
52}
53
54#[cfg(feature = "speedy")]
55impl<C: Context> Writable<C> for Signature {
56 #[inline]
57 fn write_to<T: ?Sized + Writer<C>>(&self, writer: &mut T) -> Result<(), C::Error> {
58 let bytes = self.0.as_ref();
59 assert_eq!(bytes.as_slice().len(), 64);
60 writer.write_bytes(bytes.as_slice())
61 }
62
63 #[inline]
64 fn bytes_needed(&self) -> Result<usize, C::Error> {
65 Ok(64)
66 }
67}
68
69#[derive(
71 AsMut,
72 AsRef,
73 Clone,
74 Debug,
75 Deref,
76 Deserialize,
77 Display,
78 Eq,
79 From,
80 FromStr,
81 Hash,
82 Into,
83 PartialEq,
84 Serialize,
85)]
86#[cfg_attr(feature = "speedy", derive(Readable, Writable))]
87pub struct SignatureHex(pub String);
88
89impl SignatureHex {
90 #[allow(dead_code)]
92 pub(crate) async fn mock() -> SignatureHex {
93 From::from(Signature::mock().await)
94 }
95}
96
97impl From<Signature> for SignatureHex {
98 fn from(s: Signature) -> SignatureHex {
99 SignatureHex(s.as_hex_string())
100 }
101}
102
103impl TryFrom<SignatureHex> for Signature {
104 type Error = Error;
105
106 fn try_from(sh: SignatureHex) -> Result<Signature, Error> {
107 Signature::try_from_hex_string(&sh.0)
108 }
109}
110
111#[cfg(test)]
112mod test {
113 use super::*;
114
115 test_serde_async! {Signature, test_signature_serde}
116
117 #[cfg(feature = "speedy")]
118 #[tokio::test]
119 async fn test_speedy_signature() {
120 let sig = Signature::mock().await;
121 let bytes = sig.write_to_vec().unwrap();
122 let sig2 = Signature::read_from_buffer(&bytes).unwrap();
123 assert_eq!(sig, sig2);
124 }
125}