breez_sdk_spark/signer/
lnurl_auth.rs1use std::sync::Arc;
2
3use bitcoin::bip32::{ChildNumber, DerivationPath};
4use bitcoin::secp256k1::Message;
5use breez_sdk_common::lnurl::auth::LnurlAuthSigner;
6use breez_sdk_common::lnurl::error::{LnurlError, LnurlResult};
7
8use crate::signer::{BreezSigner, HmacSigner};
9
10pub struct LnurlAuthSignerAdapter {
13 signer: Arc<dyn BreezSigner>,
14 hmac: Arc<dyn HmacSigner>,
15}
16
17impl LnurlAuthSignerAdapter {
18 pub fn new(signer: Arc<dyn BreezSigner>, hmac: Arc<dyn HmacSigner>) -> Self {
19 Self { signer, hmac }
20 }
21}
22
23#[macros::async_trait]
24impl LnurlAuthSigner for LnurlAuthSignerAdapter {
25 async fn derive_public_key(
26 &self,
27 derivation_path: &[ChildNumber],
28 ) -> LnurlResult<bitcoin::secp256k1::PublicKey> {
29 let path = DerivationPath::from(derivation_path.to_vec());
31
32 self.signer
34 .derive_public_key(&path)
35 .await
36 .map_err(|e| LnurlError::General(e.to_string()))
37 }
38
39 async fn sign_ecdsa(
40 &self,
41 msg: &[u8],
42 derivation_path: &[ChildNumber],
43 ) -> LnurlResult<Vec<u8>> {
44 let path = DerivationPath::from(derivation_path.to_vec());
45
46 let message = Message::from_digest(
48 msg.try_into()
49 .map_err(|_| LnurlError::General("Invalid lnurl message".to_string()))?,
50 );
51
52 let sig = self
54 .signer
55 .sign_ecdsa(message, &path)
56 .await
57 .map_err(|e| LnurlError::General(e.to_string()))?;
58
59 Ok(sig.serialize_der().to_vec())
61 }
62
63 async fn hmac_sha256(
64 &self,
65 key_derivation_path: &[ChildNumber],
66 input: &[u8],
67 ) -> LnurlResult<Vec<u8>> {
68 use bitcoin::hashes::Hash;
69
70 let path = DerivationPath::from(key_derivation_path.to_vec());
71
72 let hmac = self
74 .hmac
75 .hmac_sha256(&path, input)
76 .await
77 .map_err(|e| LnurlError::General(e.to_string()))?;
78
79 Ok(hmac.as_byte_array().to_vec())
81 }
82}