lwk/types/
secret_key.rs

1use crate::LwkError;
2use crate::Pset;
3use elements::bitcoin::secp256k1;
4use std::sync::Arc;
5
6/// A secret key
7#[derive(uniffi::Object, PartialEq, Eq, Debug, Clone, Copy)]
8pub struct SecretKey {
9    inner: secp256k1::SecretKey,
10}
11
12impl From<secp256k1::SecretKey> for SecretKey {
13    fn from(inner: secp256k1::SecretKey) -> Self {
14        SecretKey { inner }
15    }
16}
17
18impl From<SecretKey> for secp256k1::SecretKey {
19    fn from(value: SecretKey) -> Self {
20        value.inner
21    }
22}
23
24impl From<&SecretKey> for secp256k1::SecretKey {
25    fn from(value: &SecretKey) -> Self {
26        value.inner
27    }
28}
29
30#[uniffi::export]
31impl SecretKey {
32    /// Creates a `SecretKey` from a byte array
33    ///
34    /// The bytes can be used to create a `SecretKey` with `from_bytes()`
35    #[uniffi::constructor]
36    pub fn from_bytes(bytes: &[u8]) -> Result<Arc<Self>, LwkError> {
37        let inner = secp256k1::SecretKey::from_slice(bytes)?;
38        Ok(Arc::new(SecretKey { inner }))
39    }
40
41    /// Returns the bytes of the secret key, the bytes can be used to create a `SecretKey` with `from_bytes()`
42    pub fn bytes(&self) -> Vec<u8> {
43        self.inner.secret_bytes().to_vec()
44    }
45
46    /// Creates a `SecretKey` from a WIF (Wallet Import Format) string
47    #[uniffi::constructor]
48    pub fn from_wif(wif: &str) -> Result<Arc<Self>, LwkError> {
49        let inner = elements::bitcoin::PrivateKey::from_wif(wif)?.inner;
50        Ok(Arc::new(SecretKey { inner }))
51    }
52
53    /// Sign the given `pset`
54    pub fn sign(&self, pset: &Pset) -> Result<Arc<Pset>, LwkError> {
55        let mut pset = pset.inner();
56        lwk_signer::sign_with_seckey(self.inner, &mut pset)?;
57        Ok(Arc::new(pset.into()))
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::SecretKey;
64    use elements::bitcoin::secp256k1;
65
66    #[test]
67    fn test_secret_key() {
68        let bytes = [0xcd; 32];
69        let secp_key = secp256k1::SecretKey::from_slice(&bytes).unwrap();
70        let key: SecretKey = secp_key.into();
71        let key1 = SecretKey::from_bytes(&bytes).unwrap();
72
73        assert_eq!(key, *key1);
74        assert_eq!(&key.bytes(), &bytes);
75
76        let wif_test = "cTJTN1hGHqucsgqmYVbhU3g4eU9g5HzE1sxuSY32M1xap1K4sYHF";
77        let wif_main = "L2wTu6hQrnDMiFNWA5na6jB12ErGQqtXwqpSL7aWquJaZG8Ai3ch";
78        let key_test = SecretKey::from_wif(wif_test).unwrap();
79        let key_main = SecretKey::from_wif(wif_main).unwrap();
80        assert_eq!(key_test.bytes(), key_main.bytes());
81    }
82}