minreq_client.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. //! Minreq http Client
  2. use std::println;
  3. use async_trait::async_trait;
  4. use cashu::nuts::nut00::wallet::BlindedMessages;
  5. use cashu::nuts::nut00::{BlindedMessage, Proof};
  6. use cashu::nuts::nut01::Keys;
  7. use cashu::nuts::nut03::RequestMintResponse;
  8. use cashu::nuts::nut04::{MintRequest, PostMintResponse};
  9. use cashu::nuts::nut05::{CheckFeesRequest, CheckFeesResponse};
  10. use cashu::nuts::nut06::{SplitRequest, SplitResponse};
  11. #[cfg(feature = "nut07")]
  12. use cashu::nuts::nut07::{CheckSpendableRequest, CheckSpendableResponse};
  13. use cashu::nuts::nut08::{MeltRequest, MeltResponse};
  14. #[cfg(feature = "nut09")]
  15. use cashu::nuts::MintInfo;
  16. use cashu::nuts::*;
  17. use cashu::{Amount, Bolt11Invoice};
  18. use serde_json::Value;
  19. use tracing::debug;
  20. use url::Url;
  21. use super::join_url;
  22. use crate::client::{Client, Error};
  23. #[derive(Debug, Clone)]
  24. pub struct HttpClient {}
  25. #[async_trait(?Send)]
  26. impl Client for HttpClient {
  27. /// Get Mint Keys [NUT-01]
  28. async fn get_mint_keys(&self, mint_url: Url) -> Result<Keys, Error> {
  29. let url = join_url(mint_url, "keys")?;
  30. let keys = minreq::get(url).send()?.json::<Value>()?;
  31. let keys: Keys = serde_json::from_str(&keys.to_string())?;
  32. Ok(keys)
  33. }
  34. /// Get Keysets [NUT-02]
  35. async fn get_mint_keysets(&self, mint_url: Url) -> Result<KeysetResponse, Error> {
  36. let url = join_url(mint_url, "keysets")?;
  37. let res = minreq::get(url).send()?.json::<Value>()?;
  38. let response: Result<KeysetResponse, serde_json::Error> =
  39. serde_json::from_value(res.clone());
  40. match response {
  41. Ok(res) => Ok(res),
  42. Err(_) => Err(Error::from_json(&res.to_string())?),
  43. }
  44. }
  45. /// Request Mint [NUT-03]
  46. async fn get_request_mint(
  47. &self,
  48. mint_url: Url,
  49. amount: Amount,
  50. ) -> Result<RequestMintResponse, Error> {
  51. let mut url = join_url(mint_url, "mint")?;
  52. url.query_pairs_mut()
  53. .append_pair("amount", &amount.to_sat().to_string());
  54. let res = minreq::get(url).send()?.json::<Value>()?;
  55. let response: Result<RequestMintResponse, serde_json::Error> =
  56. serde_json::from_value(res.clone());
  57. match response {
  58. Ok(res) => Ok(res),
  59. Err(_) => Err(Error::from_json(&res.to_string())?),
  60. }
  61. }
  62. /// Mint Tokens [NUT-04]
  63. async fn post_mint(
  64. &self,
  65. mint_url: Url,
  66. blinded_messages: BlindedMessages,
  67. hash: &str,
  68. ) -> Result<PostMintResponse, Error> {
  69. let mut url = join_url(mint_url, "mint")?;
  70. url.query_pairs_mut().append_pair("hash", hash);
  71. let request = MintRequest {
  72. outputs: blinded_messages.blinded_messages,
  73. };
  74. let res = minreq::post(url)
  75. .with_json(&request)?
  76. .send()?
  77. .json::<Value>()?;
  78. let response: Result<PostMintResponse, serde_json::Error> =
  79. serde_json::from_value(res.clone());
  80. match response {
  81. Ok(res) => Ok(res),
  82. Err(_) => Err(Error::from_json(&res.to_string())?),
  83. }
  84. }
  85. /// Check Max expected fee [NUT-05]
  86. async fn post_check_fees(
  87. &self,
  88. mint_url: Url,
  89. invoice: Bolt11Invoice,
  90. ) -> Result<CheckFeesResponse, Error> {
  91. let url = join_url(mint_url, "checkfees")?;
  92. let request = CheckFeesRequest { pr: invoice };
  93. let res = minreq::post(url)
  94. .with_json(&request)?
  95. .send()?
  96. .json::<Value>()?;
  97. let response: Result<CheckFeesResponse, serde_json::Error> =
  98. serde_json::from_value(res.clone());
  99. match response {
  100. Ok(res) => Ok(res),
  101. Err(_) => Err(Error::from_json(&res.to_string())?),
  102. }
  103. }
  104. /// Melt [NUT-05]
  105. /// [Nut-08] Lightning fee return if outputs defined
  106. async fn post_melt(
  107. &self,
  108. mint_url: Url,
  109. proofs: Vec<Proof>,
  110. invoice: Bolt11Invoice,
  111. outputs: Option<Vec<BlindedMessage>>,
  112. ) -> Result<MeltResponse, Error> {
  113. let url = join_url(mint_url, "melt")?;
  114. let request = MeltRequest {
  115. proofs,
  116. pr: invoice,
  117. outputs,
  118. };
  119. let value = minreq::post(url)
  120. .with_json(&request)?
  121. .send()?
  122. .json::<Value>()?;
  123. let response: Result<MeltResponse, serde_json::Error> =
  124. serde_json::from_value(value.clone());
  125. match response {
  126. Ok(res) => Ok(res),
  127. Err(_) => Err(Error::from_json(&value.to_string())?),
  128. }
  129. }
  130. /// Split Token [NUT-06]
  131. async fn post_split(
  132. &self,
  133. mint_url: Url,
  134. split_request: SplitRequest,
  135. ) -> Result<SplitResponse, Error> {
  136. let url = join_url(mint_url, "split")?;
  137. let res = minreq::post(url).with_json(&split_request)?.send()?;
  138. println!("{:?}", res);
  139. let response: Result<SplitResponse, serde_json::Error> =
  140. serde_json::from_value(res.json::<Value>()?.clone());
  141. match response {
  142. Ok(res) if res.promises.is_some() => Ok(res),
  143. _ => Err(Error::from_json(&res.json::<Value>()?.to_string())?),
  144. }
  145. }
  146. /// Spendable check [NUT-07]
  147. #[cfg(feature = "nut07")]
  148. async fn post_check_spendable(
  149. &self,
  150. mint_url: Url,
  151. proofs: Vec<nut00::mint::Proof>,
  152. ) -> Result<CheckSpendableResponse, Error> {
  153. let url = join_url(mint_url, "check")?;
  154. let request = CheckSpendableRequest { proofs };
  155. let res = minreq::post(url)
  156. .with_json(&request)?
  157. .send()?
  158. .json::<Value>()?;
  159. let response: Result<CheckSpendableResponse, serde_json::Error> =
  160. serde_json::from_value(res.clone());
  161. match response {
  162. Ok(res) => Ok(res),
  163. Err(_) => Err(Error::from_json(&res.to_string())?),
  164. }
  165. }
  166. /// Get Mint Info [NUT-09]
  167. #[cfg(feature = "nut09")]
  168. async fn get_mint_info(&self, mint_url: Url) -> Result<MintInfo, Error> {
  169. let url = join_url(mint_url, "info")?;
  170. let res = minreq::get(url).send()?.json::<Value>()?;
  171. let response: Result<MintInfo, serde_json::Error> = serde_json::from_value(res.clone());
  172. match response {
  173. Ok(res) => Ok(res),
  174. Err(_) => Err(Error::from_json(&res.to_string())?),
  175. }
  176. }
  177. }