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;
9
10pub struct LnurlAuthSignerAdapter {
12 signer: Arc<dyn BreezSigner>,
13}
14
15impl LnurlAuthSignerAdapter {
16 pub fn new(signer: Arc<dyn BreezSigner>) -> Self {
17 Self { signer }
18 }
19}
20
21#[macros::async_trait]
22impl LnurlAuthSigner for LnurlAuthSignerAdapter {
23 async fn derive_public_key(
24 &self,
25 derivation_path: &[ChildNumber],
26 ) -> LnurlResult<bitcoin::secp256k1::PublicKey> {
27 let path = DerivationPath::from(derivation_path.to_vec());
29
30 self.signer
32 .derive_public_key(&path)
33 .await
34 .map_err(|e| LnurlError::General(e.to_string()))
35 }
36
37 async fn sign_ecdsa(
38 &self,
39 msg: &[u8],
40 derivation_path: &[ChildNumber],
41 ) -> LnurlResult<Vec<u8>> {
42 let path = DerivationPath::from(derivation_path.to_vec());
43
44 let message = Message::from_digest(
46 msg.try_into()
47 .map_err(|_| LnurlError::General("Invalid lnurl message".to_string()))?,
48 );
49
50 let sig = self
52 .signer
53 .sign_ecdsa(message, &path)
54 .await
55 .map_err(|e| LnurlError::General(e.to_string()))?;
56
57 Ok(sig.serialize_der().to_vec())
59 }
60
61 async fn hmac_sha256(
62 &self,
63 key_derivation_path: &[ChildNumber],
64 input: &[u8],
65 ) -> LnurlResult<Vec<u8>> {
66 use bitcoin::hashes::Hash;
67
68 let path = DerivationPath::from(key_derivation_path.to_vec());
69
70 let hmac = self
72 .signer
73 .hmac_sha256(&path, input)
74 .await
75 .map_err(|e| LnurlError::General(e.to_string()))?;
76
77 Ok(hmac.as_byte_array().to_vec())
79 }
80}