cdk_mintd/
setup.rs

1#[cfg(feature = "fakewallet")]
2use std::collections::HashMap;
3#[cfg(feature = "fakewallet")]
4use std::collections::HashSet;
5#[cfg(feature = "lnbits")]
6use std::sync::Arc;
7
8#[cfg(feature = "cln")]
9use anyhow::anyhow;
10use async_trait::async_trait;
11use axum::Router;
12#[cfg(feature = "fakewallet")]
13use bip39::rand::{thread_rng, Rng};
14use cdk::cdk_payment::MintPayment;
15#[cfg(feature = "lnbits")]
16use cdk::mint_url::MintUrl;
17use cdk::nuts::CurrencyUnit;
18#[cfg(any(
19    feature = "lnbits",
20    feature = "cln",
21    feature = "lnd",
22    feature = "fakewallet"
23))]
24use cdk::types::FeeReserve;
25#[cfg(feature = "lnbits")]
26use tokio::sync::Mutex;
27
28use crate::config::{self, Settings};
29#[cfg(feature = "cln")]
30use crate::expand_path;
31
32#[async_trait]
33pub trait LnBackendSetup {
34    async fn setup(
35        &self,
36        routers: &mut Vec<Router>,
37        settings: &Settings,
38        unit: CurrencyUnit,
39    ) -> anyhow::Result<impl MintPayment>;
40}
41
42#[cfg(feature = "cln")]
43#[async_trait]
44impl LnBackendSetup for config::Cln {
45    async fn setup(
46        &self,
47        _routers: &mut Vec<Router>,
48        _settings: &Settings,
49        _unit: CurrencyUnit,
50    ) -> anyhow::Result<cdk_cln::Cln> {
51        let cln_socket = expand_path(
52            self.rpc_path
53                .to_str()
54                .ok_or(anyhow!("cln socket not defined"))?,
55        )
56        .ok_or(anyhow!("cln socket not defined"))?;
57
58        let fee_reserve = FeeReserve {
59            min_fee_reserve: self.reserve_fee_min,
60            percent_fee_reserve: self.fee_percent,
61        };
62
63        let cln = cdk_cln::Cln::new(cln_socket, fee_reserve).await?;
64
65        Ok(cln)
66    }
67}
68
69#[cfg(feature = "lnbits")]
70#[async_trait]
71impl LnBackendSetup for config::LNbits {
72    async fn setup(
73        &self,
74        routers: &mut Vec<Router>,
75        settings: &Settings,
76        _unit: CurrencyUnit,
77    ) -> anyhow::Result<cdk_lnbits::LNbits> {
78        let admin_api_key = &self.admin_api_key;
79        let invoice_api_key = &self.invoice_api_key;
80
81        // Channel used for lnbits web hook
82        let (sender, receiver) = tokio::sync::mpsc::channel(8);
83        let webhook_endpoint = "/webhook/lnbits/sat/invoice";
84
85        let mint_url: MintUrl = settings.info.url.parse()?;
86        let webhook_url = mint_url.join(webhook_endpoint)?;
87
88        let fee_reserve = FeeReserve {
89            min_fee_reserve: self.reserve_fee_min,
90            percent_fee_reserve: self.fee_percent,
91        };
92
93        let lnbits = cdk_lnbits::LNbits::new(
94            admin_api_key.clone(),
95            invoice_api_key.clone(),
96            self.lnbits_api.clone(),
97            fee_reserve,
98            Arc::new(Mutex::new(Some(receiver))),
99            webhook_url.to_string(),
100        )
101        .await?;
102
103        let router = lnbits
104            .create_invoice_webhook_router(webhook_endpoint, sender)
105            .await?;
106
107        routers.push(router);
108
109        Ok(lnbits)
110    }
111}
112
113#[cfg(feature = "lnd")]
114#[async_trait]
115impl LnBackendSetup for config::Lnd {
116    async fn setup(
117        &self,
118        _routers: &mut Vec<Router>,
119        _settings: &Settings,
120        _unit: CurrencyUnit,
121    ) -> anyhow::Result<cdk_lnd::Lnd> {
122        let address = &self.address;
123        let cert_file = &self.cert_file;
124        let macaroon_file = &self.macaroon_file;
125
126        let fee_reserve = FeeReserve {
127            min_fee_reserve: self.reserve_fee_min,
128            percent_fee_reserve: self.fee_percent,
129        };
130
131        let lnd = cdk_lnd::Lnd::new(
132            address.to_string(),
133            cert_file.clone(),
134            macaroon_file.clone(),
135            fee_reserve,
136        )
137        .await?;
138
139        Ok(lnd)
140    }
141}
142
143#[cfg(feature = "fakewallet")]
144#[async_trait]
145impl LnBackendSetup for config::FakeWallet {
146    async fn setup(
147        &self,
148        _router: &mut Vec<Router>,
149        _settings: &Settings,
150        _unit: CurrencyUnit,
151    ) -> anyhow::Result<cdk_fake_wallet::FakeWallet> {
152        let fee_reserve = FeeReserve {
153            min_fee_reserve: self.reserve_fee_min,
154            percent_fee_reserve: self.fee_percent,
155        };
156
157        // calculate random delay time
158        let mut rng = thread_rng();
159        let delay_time = rng.gen_range(self.min_delay_time..=self.max_delay_time);
160
161        let fake_wallet = cdk_fake_wallet::FakeWallet::new(
162            fee_reserve,
163            HashMap::default(),
164            HashSet::default(),
165            delay_time,
166        );
167
168        Ok(fake_wallet)
169    }
170}
171
172#[cfg(feature = "grpc-processor")]
173#[async_trait]
174impl LnBackendSetup for config::GrpcProcessor {
175    async fn setup(
176        &self,
177        _routers: &mut Vec<Router>,
178        _settings: &Settings,
179        _unit: CurrencyUnit,
180    ) -> anyhow::Result<cdk_payment_processor::PaymentProcessorClient> {
181        let payment_processor = cdk_payment_processor::PaymentProcessorClient::new(
182            &self.addr,
183            self.port,
184            self.tls_dir.clone(),
185        )
186        .await?;
187
188        Ok(payment_processor)
189    }
190}