setup.rs 4.9 KB

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