1use crate::LwkError;
2use crate::Pset;
3use elements::bitcoin::secp256k1;
4use std::sync::Arc;
5
6#[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 #[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 pub fn bytes(&self) -> Vec<u8> {
43 self.inner.secret_bytes().to_vec()
44 }
45
46 #[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 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}