breez_sdk_spark/signer/
rtsync.rs1use anyhow::anyhow;
2use bitcoin::bip32::DerivationPath;
3use breez_sdk_common::sync::SyncSigner;
4use std::sync::Arc;
5
6use crate::{
7 Network,
8 signer::{BreezSigner, EciesSigner},
9};
10
11const SIGNING_DERIVATION_PATH: &str = "m/1220588449'/0'/0'/0/0";
12const SIGNING_DERIVATION_PATH_TEST: &str = "m/1220588449'/1'/0'/0/0";
13const ENCRYPTION_DERIVATION_PATH: &str = "m/1782705014'/0'/0'/0/0";
14const ENCRYPTION_DERIVATION_PATH_TEST: &str = "m/1782705014'/1'/0'/0/0";
15
16pub struct RTSyncSigner {
17 signer: Arc<dyn BreezSigner>,
18 ecies: Arc<dyn EciesSigner>,
19 signing_path: DerivationPath,
20 encryption_path: DerivationPath,
21}
22
23impl RTSyncSigner {
24 pub fn new(
25 signer: Arc<dyn BreezSigner>,
26 ecies: Arc<dyn EciesSigner>,
27 network: Network,
28 ) -> Result<Self, bitcoin::bip32::Error> {
29 let signing_path: DerivationPath = match network {
30 Network::Mainnet => SIGNING_DERIVATION_PATH,
31 Network::Regtest => SIGNING_DERIVATION_PATH_TEST,
32 }
33 .parse()?;
34 let encryption_path: DerivationPath = match network {
35 Network::Mainnet => ENCRYPTION_DERIVATION_PATH,
36 Network::Regtest => ENCRYPTION_DERIVATION_PATH_TEST,
37 }
38 .parse()?;
39
40 Ok(Self {
41 signer,
42 ecies,
43 signing_path,
44 encryption_path,
45 })
46 }
47}
48
49#[macros::async_trait]
50impl SyncSigner for RTSyncSigner {
51 async fn sign_ecdsa_recoverable(&self, data: &[u8]) -> anyhow::Result<Vec<u8>> {
52 use bitcoin::hashes::{Hash, sha256};
53 use bitcoin::secp256k1::Message;
54
55 let hash = sha256::Hash::hash(sha256::Hash::hash(data).as_ref());
57 let message = Message::from_digest(hash.to_byte_array());
58 let sig = self
59 .signer
60 .sign_ecdsa_recoverable(message, &self.signing_path)
61 .await
62 .map_err(|e| anyhow!(e.to_string()))?;
63
64 let (recovery_id, sig_bytes) = sig.serialize_compact();
66 let mut complete_signature = vec![31u8.saturating_add(
67 u8::try_from(recovery_id.to_i32()).map_err(|e| anyhow!(e.to_string()))?,
68 )];
69 complete_signature.extend_from_slice(&sig_bytes);
70 Ok(complete_signature)
71 }
72
73 async fn encrypt_ecies(&self, msg: Vec<u8>) -> anyhow::Result<Vec<u8>> {
74 self.ecies
75 .encrypt_ecies(&msg, &self.encryption_path)
76 .await
77 .map_err(|e| anyhow!(e.to_string()))
78 }
79
80 async fn decrypt_ecies(&self, msg: Vec<u8>) -> anyhow::Result<Vec<u8>> {
81 self.ecies
82 .decrypt_ecies(&msg, &self.encryption_path)
83 .await
84 .map_err(|e| anyhow!(e.to_string()))
85 }
86}