payment_processor.rs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #[cfg(feature = "fake")]
  2. use std::collections::{HashMap, HashSet};
  3. use std::env;
  4. use std::path::PathBuf;
  5. #[cfg(any(feature = "cln", feature = "lnd", feature = "fake"))]
  6. use std::sync::Arc;
  7. #[cfg(any(feature = "cln", feature = "lnd", feature = "fake"))]
  8. use anyhow::bail;
  9. #[cfg(any(feature = "cln", feature = "lnd", feature = "fake"))]
  10. use cdk_common::common::FeeReserve;
  11. #[cfg(any(feature = "cln", feature = "lnd", feature = "fake"))]
  12. use cdk_common::payment::{self, MintPayment};
  13. use cdk_common::Amount;
  14. #[cfg(feature = "fake")]
  15. use cdk_fake_wallet::FakeWallet;
  16. use serde::{Deserialize, Serialize};
  17. #[cfg(any(feature = "cln", feature = "lnd", feature = "fake"))]
  18. use tokio::signal;
  19. use tracing_subscriber::EnvFilter;
  20. pub const ENV_LN_BACKEND: &str = "CDK_PAYMENT_PROCESSOR_LN_BACKEND";
  21. pub const ENV_LISTEN_HOST: &str = "CDK_PAYMENT_PROCESSOR_LISTEN_HOST";
  22. pub const ENV_LISTEN_PORT: &str = "CDK_PAYMENT_PROCESSOR_LISTEN_PORT";
  23. pub const ENV_PAYMENT_PROCESSOR_TLS_DIR: &str = "CDK_PAYMENT_PROCESSOR_TLS_DIR";
  24. // CLN
  25. pub const ENV_CLN_RPC_PATH: &str = "CDK_PAYMENT_PROCESSOR_CLN_RPC_PATH";
  26. pub const ENV_CLN_BOLT12: &str = "CDK_PAYMENT_PROCESSOR_CLN_BOLT12";
  27. pub const ENV_FEE_PERCENT: &str = "CDK_PAYMENT_PROCESSOR_FEE_PERCENT";
  28. pub const ENV_RESERVE_FEE_MIN: &str = "CDK_PAYMENT_PROCESSOR_RESERVE_FEE_MIN";
  29. // LND environment variables
  30. pub const ENV_LND_ADDRESS: &str = "CDK_PAYMENT_PROCESSOR_LND_ADDRESS";
  31. pub const ENV_LND_CERT_FILE: &str = "CDK_PAYMENT_PROCESSOR_LND_CERT_FILE";
  32. pub const ENV_LND_MACAROON_FILE: &str = "CDK_PAYMENT_PROCESSOR_LND_MACAROON_FILE";
  33. #[tokio::main]
  34. async fn main() -> anyhow::Result<()> {
  35. let default_filter = "debug";
  36. let sqlx_filter = "sqlx=warn";
  37. let hyper_filter = "hyper=warn";
  38. let h2_filter = "h2=warn";
  39. let rustls_filter = "rustls=warn";
  40. let env_filter = EnvFilter::new(format!(
  41. "{default_filter},{sqlx_filter},{hyper_filter},{h2_filter},{rustls_filter}"
  42. ));
  43. tracing_subscriber::fmt().with_env_filter(env_filter).init();
  44. #[cfg(any(feature = "cln", feature = "lnd", feature = "fake"))]
  45. {
  46. let ln_backend: String = env::var(ENV_LN_BACKEND)?;
  47. let listen_addr: String = env::var(ENV_LISTEN_HOST)?;
  48. let listen_port: u16 = env::var(ENV_LISTEN_PORT)?.parse()?;
  49. let tls_dir: Option<PathBuf> = env::var(ENV_PAYMENT_PROCESSOR_TLS_DIR)
  50. .ok()
  51. .map(PathBuf::from);
  52. let ln_backed: Arc<dyn MintPayment<Err = payment::Error> + Send + Sync> =
  53. match ln_backend.to_uppercase().as_str() {
  54. #[cfg(feature = "cln")]
  55. "CLN" => {
  56. let cln_settings = Cln::default().from_env();
  57. let fee_reserve = FeeReserve {
  58. min_fee_reserve: cln_settings.reserve_fee_min,
  59. percent_fee_reserve: cln_settings.fee_percent,
  60. };
  61. Arc::new(cdk_cln::Cln::new(cln_settings.rpc_path, fee_reserve).await?)
  62. }
  63. #[cfg(feature = "fake")]
  64. "FAKEWALLET" => {
  65. let fee_reserve = FeeReserve {
  66. min_fee_reserve: 1.into(),
  67. percent_fee_reserve: 0.0,
  68. };
  69. let fake_wallet =
  70. FakeWallet::new(fee_reserve, HashMap::default(), HashSet::default(), 0);
  71. Arc::new(fake_wallet)
  72. }
  73. #[cfg(feature = "lnd")]
  74. "LND" => {
  75. let lnd_settings = Lnd::default().from_env();
  76. let fee_reserve = FeeReserve {
  77. min_fee_reserve: lnd_settings.reserve_fee_min,
  78. percent_fee_reserve: lnd_settings.fee_percent,
  79. };
  80. Arc::new(
  81. cdk_lnd::Lnd::new(
  82. lnd_settings.address,
  83. lnd_settings.cert_file,
  84. lnd_settings.macaroon_file,
  85. fee_reserve,
  86. )
  87. .await?,
  88. )
  89. }
  90. _ => {
  91. bail!("Unknown payment processor");
  92. }
  93. };
  94. let mut server = cdk_payment_processor::PaymentProcessorServer::new(
  95. ln_backed,
  96. &listen_addr,
  97. listen_port,
  98. )?;
  99. server.start(tls_dir).await?;
  100. // Wait for shutdown signal
  101. signal::ctrl_c().await?;
  102. server.stop().await?;
  103. }
  104. Ok(())
  105. }
  106. #[derive(Debug, Clone, Serialize, Deserialize, Default)]
  107. pub struct Cln {
  108. pub rpc_path: PathBuf,
  109. #[serde(default)]
  110. pub bolt12: bool,
  111. pub fee_percent: f32,
  112. pub reserve_fee_min: Amount,
  113. }
  114. impl Cln {
  115. pub fn from_env(mut self) -> Self {
  116. // RPC Path
  117. if let Ok(path) = env::var(ENV_CLN_RPC_PATH) {
  118. self.rpc_path = PathBuf::from(path);
  119. }
  120. // BOLT12 flag
  121. if let Ok(bolt12_str) = env::var(ENV_CLN_BOLT12) {
  122. if let Ok(bolt12) = bolt12_str.parse() {
  123. self.bolt12 = bolt12;
  124. }
  125. }
  126. // Fee percent
  127. if let Ok(fee_str) = env::var(ENV_FEE_PERCENT) {
  128. if let Ok(fee) = fee_str.parse() {
  129. self.fee_percent = fee;
  130. }
  131. }
  132. // Reserve fee minimum
  133. if let Ok(reserve_fee_str) = env::var(ENV_RESERVE_FEE_MIN) {
  134. if let Ok(reserve_fee) = reserve_fee_str.parse::<u64>() {
  135. self.reserve_fee_min = reserve_fee.into();
  136. }
  137. }
  138. self
  139. }
  140. }
  141. #[derive(Debug, Clone, Serialize, Deserialize, Default)]
  142. pub struct Lnd {
  143. pub address: String,
  144. pub cert_file: PathBuf,
  145. pub macaroon_file: PathBuf,
  146. pub fee_percent: f32,
  147. pub reserve_fee_min: Amount,
  148. }
  149. impl Lnd {
  150. pub fn from_env(mut self) -> Self {
  151. if let Ok(address) = env::var(ENV_LND_ADDRESS) {
  152. self.address = address;
  153. }
  154. if let Ok(cert_path) = env::var(ENV_LND_CERT_FILE) {
  155. self.cert_file = PathBuf::from(cert_path);
  156. }
  157. if let Ok(macaroon_path) = env::var(ENV_LND_MACAROON_FILE) {
  158. self.macaroon_file = PathBuf::from(macaroon_path);
  159. }
  160. if let Ok(fee_str) = env::var(ENV_FEE_PERCENT) {
  161. if let Ok(fee) = fee_str.parse() {
  162. self.fee_percent = fee;
  163. }
  164. }
  165. if let Ok(reserve_fee_str) = env::var(ENV_RESERVE_FEE_MIN) {
  166. if let Ok(reserve_fee) = reserve_fee_str.parse::<u64>() {
  167. self.reserve_fee_min = reserve_fee.into();
  168. }
  169. }
  170. self
  171. }
  172. }