setup.rs 6.1 KB

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