payment.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. //! CDK Mint Lightning
  2. use std::pin::Pin;
  3. use async_trait::async_trait;
  4. use cashu::MeltOptions;
  5. use futures::Stream;
  6. use lightning_invoice::ParseOrSemanticError;
  7. use serde::{Deserialize, Serialize};
  8. use serde_json::Value;
  9. use thiserror::Error;
  10. use crate::nuts::{CurrencyUnit, MeltQuoteState, MintQuoteState};
  11. use crate::{mint, Amount};
  12. /// CDK Lightning Error
  13. #[derive(Debug, Error)]
  14. pub enum Error {
  15. /// Invoice already paid
  16. #[error("Invoice already paid")]
  17. InvoiceAlreadyPaid,
  18. /// Invoice pay pending
  19. #[error("Invoice pay is pending")]
  20. InvoicePaymentPending,
  21. /// Unsupported unit
  22. #[error("Unsupported unit")]
  23. UnsupportedUnit,
  24. /// Unsupported payment option
  25. #[error("Unsupported payment option")]
  26. UnsupportedPaymentOption,
  27. /// Payment state is unknown
  28. #[error("Payment state is unknown")]
  29. UnknownPaymentState,
  30. /// Lightning Error
  31. #[error(transparent)]
  32. Lightning(Box<dyn std::error::Error + Send + Sync>),
  33. /// Serde Error
  34. #[error(transparent)]
  35. Serde(#[from] serde_json::Error),
  36. /// AnyHow Error
  37. #[error(transparent)]
  38. Anyhow(#[from] anyhow::Error),
  39. /// Parse Error
  40. #[error(transparent)]
  41. Parse(#[from] ParseOrSemanticError),
  42. /// Amount Error
  43. #[error(transparent)]
  44. Amount(#[from] crate::amount::Error),
  45. /// NUT04 Error
  46. #[error(transparent)]
  47. NUT04(#[from] crate::nuts::nut04::Error),
  48. /// NUT05 Error
  49. #[error(transparent)]
  50. NUT05(#[from] crate::nuts::nut05::Error),
  51. /// NUT23 Error
  52. #[error(transparent)]
  53. NUT23(#[from] crate::nuts::nut23::Error),
  54. /// Custom
  55. #[error("`{0}`")]
  56. Custom(String),
  57. }
  58. /// Mint payment trait
  59. #[async_trait]
  60. pub trait MintPayment {
  61. /// Mint Lightning Error
  62. type Err: Into<Error> + From<Error>;
  63. /// Base Settings
  64. async fn get_settings(&self) -> Result<serde_json::Value, Self::Err>;
  65. /// Create a new invoice
  66. async fn create_incoming_payment_request(
  67. &self,
  68. amount: Amount,
  69. unit: &CurrencyUnit,
  70. description: String,
  71. unix_expiry: Option<u64>,
  72. ) -> Result<CreateIncomingPaymentResponse, Self::Err>;
  73. /// Get payment quote
  74. /// Used to get fee and amount required for a payment request
  75. async fn get_payment_quote(
  76. &self,
  77. request: &str,
  78. unit: &CurrencyUnit,
  79. options: Option<MeltOptions>,
  80. ) -> Result<PaymentQuoteResponse, Self::Err>;
  81. /// Pay request
  82. async fn make_payment(
  83. &self,
  84. melt_quote: mint::MeltQuote,
  85. partial_amount: Option<Amount>,
  86. max_fee_amount: Option<Amount>,
  87. ) -> Result<MakePaymentResponse, Self::Err>;
  88. /// Listen for invoices to be paid to the mint
  89. /// Returns a stream of request_lookup_id once invoices are paid
  90. async fn wait_any_incoming_payment(
  91. &self,
  92. ) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err>;
  93. /// Is wait invoice active
  94. fn is_wait_invoice_active(&self) -> bool;
  95. /// Cancel wait invoice
  96. fn cancel_wait_invoice(&self);
  97. /// Check the status of an incoming payment
  98. async fn check_incoming_payment_status(
  99. &self,
  100. request_lookup_id: &str,
  101. ) -> Result<MintQuoteState, Self::Err>;
  102. /// Check the status of an outgoing payment
  103. async fn check_outgoing_payment(
  104. &self,
  105. request_lookup_id: &str,
  106. ) -> Result<MakePaymentResponse, Self::Err>;
  107. }
  108. /// Create incoming payment response
  109. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  110. pub struct CreateIncomingPaymentResponse {
  111. /// Id that is used to look up the payment from the ln backend
  112. pub request_lookup_id: String,
  113. /// Payment request
  114. pub request: String,
  115. /// Unix Expiry of Invoice
  116. pub expiry: Option<u64>,
  117. }
  118. /// Payment response
  119. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  120. pub struct MakePaymentResponse {
  121. /// Payment hash
  122. pub payment_lookup_id: String,
  123. /// Payment proof
  124. pub payment_proof: Option<String>,
  125. /// Status
  126. pub status: MeltQuoteState,
  127. /// Total Amount Spent
  128. pub total_spent: Amount,
  129. /// Unit of total spent
  130. pub unit: CurrencyUnit,
  131. }
  132. /// Payment quote response
  133. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  134. pub struct PaymentQuoteResponse {
  135. /// Request look up id
  136. pub request_lookup_id: String,
  137. /// Amount
  138. pub amount: Amount,
  139. /// Fee required for melt
  140. pub fee: Amount,
  141. /// Status
  142. pub state: MeltQuoteState,
  143. }
  144. /// Ln backend settings
  145. #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
  146. pub struct Bolt11Settings {
  147. /// MPP supported
  148. pub mpp: bool,
  149. /// Base unit of backend
  150. pub unit: CurrencyUnit,
  151. /// Invoice Description supported
  152. pub invoice_description: bool,
  153. /// Paying amountless invoices supported
  154. pub amountless: bool,
  155. }
  156. impl TryFrom<Bolt11Settings> for Value {
  157. type Error = crate::error::Error;
  158. fn try_from(value: Bolt11Settings) -> Result<Self, Self::Error> {
  159. serde_json::to_value(value).map_err(|err| err.into())
  160. }
  161. }
  162. impl TryFrom<Value> for Bolt11Settings {
  163. type Error = crate::error::Error;
  164. fn try_from(value: Value) -> Result<Self, Self::Error> {
  165. serde_json::from_value(value).map_err(|err| err.into())
  166. }
  167. }