breez_sdk_core/lnurl/
auth.rs

1use std::sync::Arc;
2
3use gl_client::bitcoin::{
4    hashes::{sha256, Hash, HashEngine, Hmac, HmacEngine},
5    secp256k1::{Message, Secp256k1},
6    util::bip32::{ChildNumber, ExtendedPubKey},
7};
8use sdk_common::prelude::{LnUrlError, LnUrlResult, LnurlAuthSigner};
9
10use crate::node_api::NodeAPI;
11
12pub(crate) struct SdkLnurlAuthSigner {
13    node_api: Arc<dyn NodeAPI>,
14}
15
16impl SdkLnurlAuthSigner {
17    pub fn new(node_api: Arc<dyn NodeAPI>) -> Self {
18        Self { node_api }
19    }
20}
21
22#[tonic::async_trait]
23impl LnurlAuthSigner for SdkLnurlAuthSigner {
24    async fn derive_bip32_pub_key(&self, derivation_path: &[ChildNumber]) -> LnUrlResult<Vec<u8>> {
25        let xpriv = self.node_api.derive_bip32_key(derivation_path.to_vec()).await?;
26        Ok(ExtendedPubKey::from_priv(&Secp256k1::new(), &xpriv)
27            .encode()
28            .to_vec())
29    }
30
31    async fn sign_ecdsa(&self, msg: &[u8], derivation_path: &[ChildNumber]) -> LnUrlResult<Vec<u8>> {
32        let xpriv = self.node_api.derive_bip32_key(derivation_path.to_vec()).await?;
33        let sig = Secp256k1::new().sign_ecdsa(
34            &Message::from_slice(msg).map_err(|_| LnUrlError::generic("Failed to sign"))?,
35            &xpriv.private_key,
36        );
37        Ok(sig.serialize_der().to_vec())
38    }
39
40    async fn hmac_sha256(
41        &self,
42        key_derivation_path: &[ChildNumber],
43        input: &[u8],
44    ) -> LnUrlResult<Vec<u8>> {
45        let priv_key = self
46            .node_api
47            .derive_bip32_key(key_derivation_path.to_vec()).await?;
48        let mut engine = HmacEngine::<sha256::Hash>::new(priv_key.encode().as_slice());
49        engine.input(input);
50        Ok(Hmac::<sha256::Hash>::from_engine(engine)
51            .as_inner()
52            .to_vec())
53    }
54}