Skip to main content

agglayer_primitives/
signature.rs

1use alloy_primitives::Signature as AlloySignature;
2use k256::ecdsa;
3
4use super::{Address, SignatureError, B256, U256};
5
6/// A wrapper over [AlloySignature] with custom serialization.
7#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
8#[cfg_attr(feature = "testutils", derive(arbitrary::Arbitrary))]
9#[serde(from = "compat::Signature", into = "compat::Signature")]
10pub struct Signature(AlloySignature);
11
12impl Signature {
13    #[inline]
14    pub fn from_signature_and_parity(sig: ecdsa::Signature, v: bool) -> Self {
15        AlloySignature::from_signature_and_parity(sig, v).into()
16    }
17
18    #[inline]
19    pub fn new(r: U256, s: U256, v: bool) -> Self {
20        AlloySignature::new(r, s, v).into()
21    }
22
23    #[inline]
24    pub fn recover_address_from_prehash(&self, prehash: &B256) -> Result<Address, SignatureError> {
25        self.0
26            .recover_address_from_prehash(prehash)
27            .map(Address::from)
28    }
29
30    #[inline]
31    pub fn as_primitive_signature(&self) -> &AlloySignature {
32        &self.0
33    }
34
35    #[inline]
36    pub fn as_bytes(&self) -> [u8; 65] {
37        self.0.as_bytes()
38    }
39
40    #[inline]
41    pub fn r(&self) -> U256 {
42        self.0.r()
43    }
44
45    #[inline]
46    pub fn s(&self) -> U256 {
47        self.0.s()
48    }
49
50    #[inline]
51    pub fn v(&self) -> bool {
52        self.0.v()
53    }
54}
55
56impl From<AlloySignature> for Signature {
57    #[inline]
58    fn from(ps: AlloySignature) -> Self {
59        Self(ps)
60    }
61}
62
63impl From<Signature> for AlloySignature {
64    #[inline]
65    fn from(value: Signature) -> Self {
66        value.0
67    }
68}
69
70impl TryFrom<&[u8]> for Signature {
71    type Error = SignatureError;
72
73    #[inline]
74    fn try_from(sig: &[u8]) -> Result<Self, Self::Error> {
75        sig.try_into().map(Self)
76    }
77}
78
79impl std::str::FromStr for Signature {
80    type Err = <AlloySignature as std::str::FromStr>::Err;
81
82    #[inline]
83    fn from_str(s: &str) -> Result<Self, Self::Err> {
84        s.parse().map(Self)
85    }
86}
87
88/// Helpers for serialization / deserialization format compatibility.
89mod compat {
90    use super::U256;
91
92    #[derive(serde::Serialize, serde::Deserialize)]
93    pub struct Signature {
94        r: U256,
95        s: U256,
96        odd_y_parity: bool,
97    }
98
99    impl Signature {
100        #[inline]
101        fn new(r: U256, s: U256, odd_y_parity: bool) -> Self {
102            Self { r, s, odd_y_parity }
103        }
104    }
105
106    impl From<super::Signature> for Signature {
107        #[inline]
108        fn from(sig: super::Signature) -> Self {
109            Self::new(sig.0.r(), sig.0.s(), sig.0.v())
110        }
111    }
112
113    impl From<Signature> for super::Signature {
114        #[inline]
115        fn from(sig: Signature) -> Self {
116            let Signature { r, s, odd_y_parity } = sig;
117            Self::new(r, s, odd_y_parity)
118        }
119    }
120}