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