123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- use std::collections::{HashMap, HashSet};
- use std::sync::Arc;
- use anyhow::{anyhow, bail};
- use axum::{async_trait, Router};
- use cdk::cdk_lightning::MintLightning;
- use cdk::mint::FeeReserve;
- use cdk::mint_url::MintUrl;
- use cdk::nuts::CurrencyUnit;
- use rand::Rng;
- use tokio::sync::Mutex;
- use url::Url;
- use crate::config::{self, Settings};
- use crate::expand_path;
- #[async_trait]
- pub trait LnBackendSetup {
- async fn setup(
- &self,
- routers: &mut Vec<Router>,
- settings: &Settings,
- unit: CurrencyUnit,
- ) -> anyhow::Result<impl MintLightning>;
- }
- #[async_trait]
- impl LnBackendSetup for config::Cln {
- async fn setup(
- &self,
- _routers: &mut Vec<Router>,
- _settings: &Settings,
- _unit: CurrencyUnit,
- ) -> anyhow::Result<cdk_cln::Cln> {
- let cln_socket = expand_path(
- self.rpc_path
- .to_str()
- .ok_or(anyhow!("cln socket not defined"))?,
- )
- .ok_or(anyhow!("cln socket not defined"))?;
- let fee_reserve = FeeReserve {
- min_fee_reserve: self.reserve_fee_min,
- percent_fee_reserve: self.fee_percent,
- };
- let cln = cdk_cln::Cln::new(cln_socket, fee_reserve).await?;
- Ok(cln)
- }
- }
- #[async_trait]
- impl LnBackendSetup for config::Strike {
- async fn setup(
- &self,
- routers: &mut Vec<Router>,
- settings: &Settings,
- unit: CurrencyUnit,
- ) -> anyhow::Result<cdk_strike::Strike> {
- let api_key = &self.api_key;
- // Channel used for strike web hook
- let (sender, receiver) = tokio::sync::mpsc::channel(8);
- let webhook_endpoint = format!("/webhook/{}/invoice", unit);
- let mint_url: MintUrl = settings.info.url.parse()?;
- let webhook_url = mint_url.join(&webhook_endpoint)?;
- let strike = cdk_strike::Strike::new(
- api_key.clone(),
- unit,
- Arc::new(Mutex::new(Some(receiver))),
- webhook_url.to_string(),
- )
- .await?;
- let router = strike
- .create_invoice_webhook(&webhook_endpoint, sender)
- .await?;
- routers.push(router);
- Ok(strike)
- }
- }
- #[async_trait]
- impl LnBackendSetup for config::LNbits {
- async fn setup(
- &self,
- routers: &mut Vec<Router>,
- settings: &Settings,
- _unit: CurrencyUnit,
- ) -> anyhow::Result<cdk_lnbits::LNbits> {
- let admin_api_key = &self.admin_api_key;
- let invoice_api_key = &self.invoice_api_key;
- // Channel used for lnbits web hook
- let (sender, receiver) = tokio::sync::mpsc::channel(8);
- let webhook_endpoint = "/webhook/lnbits/sat/invoice";
- let mint_url: MintUrl = settings.info.url.parse()?;
- let webhook_url = mint_url.join(webhook_endpoint)?;
- let fee_reserve = FeeReserve {
- min_fee_reserve: self.reserve_fee_min,
- percent_fee_reserve: self.fee_percent,
- };
- let lnbits = cdk_lnbits::LNbits::new(
- admin_api_key.clone(),
- invoice_api_key.clone(),
- self.lnbits_api.clone(),
- fee_reserve,
- Arc::new(Mutex::new(Some(receiver))),
- webhook_url.to_string(),
- )
- .await?;
- let router = lnbits
- .create_invoice_webhook_router(webhook_endpoint, sender)
- .await?;
- routers.push(router);
- Ok(lnbits)
- }
- }
- #[async_trait]
- impl LnBackendSetup for config::Phoenixd {
- async fn setup(
- &self,
- routers: &mut Vec<Router>,
- settings: &Settings,
- _unit: CurrencyUnit,
- ) -> anyhow::Result<cdk_phoenixd::Phoenixd> {
- let api_password = &self.api_password;
- let api_url = &self.api_url;
- let fee_reserve = FeeReserve {
- min_fee_reserve: self.reserve_fee_min,
- percent_fee_reserve: self.fee_percent,
- };
- if fee_reserve.percent_fee_reserve < 0.04 {
- bail!("Fee reserve is too low needs to be at least 0.02");
- }
- let webhook_endpoint = "/webhook/phoenixd";
- let mint_url = Url::parse(&settings.info.url)?;
- let webhook_url = mint_url.join(webhook_endpoint)?.to_string();
- let (sender, receiver) = tokio::sync::mpsc::channel(8);
- let phoenixd = cdk_phoenixd::Phoenixd::new(
- api_password.to_string(),
- api_url.to_string(),
- fee_reserve,
- Arc::new(Mutex::new(Some(receiver))),
- webhook_url,
- )?;
- let router = phoenixd
- .create_invoice_webhook(webhook_endpoint, sender)
- .await?;
- routers.push(router);
- Ok(phoenixd)
- }
- }
- #[async_trait]
- impl LnBackendSetup for config::Lnd {
- async fn setup(
- &self,
- _routers: &mut Vec<Router>,
- _settings: &Settings,
- _unit: CurrencyUnit,
- ) -> anyhow::Result<cdk_lnd::Lnd> {
- let address = &self.address;
- let cert_file = &self.cert_file;
- let macaroon_file = &self.macaroon_file;
- let fee_reserve = FeeReserve {
- min_fee_reserve: self.reserve_fee_min,
- percent_fee_reserve: self.fee_percent,
- };
- let lnd = cdk_lnd::Lnd::new(
- address.to_string(),
- cert_file.clone(),
- macaroon_file.clone(),
- fee_reserve,
- )
- .await?;
- Ok(lnd)
- }
- }
- #[async_trait]
- impl LnBackendSetup for config::FakeWallet {
- async fn setup(
- &self,
- _router: &mut Vec<Router>,
- _settings: &Settings,
- _unit: CurrencyUnit,
- ) -> anyhow::Result<cdk_fake_wallet::FakeWallet> {
- let fee_reserve = FeeReserve {
- min_fee_reserve: self.reserve_fee_min,
- percent_fee_reserve: self.fee_percent,
- };
- // calculate random delay time
- let mut rng = rand::thread_rng();
- let delay_time = rng.gen_range(self.min_delay_time..=self.max_delay_time);
- let fake_wallet = cdk_fake_wallet::FakeWallet::new(
- fee_reserve,
- HashMap::default(),
- HashSet::default(),
- delay_time,
- );
- Ok(fake_wallet)
- }
- }
|