setup.rs 5.1 KB

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