lib.rs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //! Axum server for Mint
  2. #![doc = include_str!("../README.md")]
  3. #![warn(missing_docs)]
  4. #![warn(rustdoc::bare_urls)]
  5. use std::sync::Arc;
  6. use anyhow::Result;
  7. #[cfg(feature = "auth")]
  8. use auth::create_auth_router;
  9. use axum::middleware::from_fn;
  10. use axum::response::Response;
  11. use axum::routing::{get, post};
  12. use axum::Router;
  13. use cache::HttpCache;
  14. use cdk::mint::Mint;
  15. use router_handlers::*;
  16. #[cfg(feature = "auth")]
  17. mod auth;
  18. pub mod cache;
  19. mod router_handlers;
  20. mod ws;
  21. #[cfg(feature = "swagger")]
  22. mod swagger_imports {
  23. pub use cdk::amount::Amount;
  24. pub use cdk::error::{ErrorCode, ErrorResponse};
  25. pub use cdk::nuts::nut00::{
  26. BlindSignature, BlindedMessage, CurrencyUnit, PaymentMethod, Proof, Witness,
  27. };
  28. pub use cdk::nuts::nut01::{Keys, KeysResponse, PublicKey, SecretKey};
  29. pub use cdk::nuts::nut02::{KeySet, KeySetInfo, KeysetResponse};
  30. pub use cdk::nuts::nut03::{SwapRequest, SwapResponse};
  31. pub use cdk::nuts::nut04::{
  32. MintBolt11Request, MintBolt11Response, MintMethodSettings, MintQuoteBolt11Request,
  33. MintQuoteBolt11Response,
  34. };
  35. pub use cdk::nuts::nut05::{
  36. MeltBolt11Request, MeltMethodSettings, MeltQuoteBolt11Request, MeltQuoteBolt11Response,
  37. };
  38. pub use cdk::nuts::nut06::{ContactInfo, MintInfo, MintVersion, Nuts, SupportedSettings};
  39. pub use cdk::nuts::nut07::{CheckStateRequest, CheckStateResponse, ProofState, State};
  40. pub use cdk::nuts::nut09::{RestoreRequest, RestoreResponse};
  41. pub use cdk::nuts::nut11::P2PKWitness;
  42. pub use cdk::nuts::nut12::{BlindSignatureDleq, ProofDleq};
  43. pub use cdk::nuts::nut14::HTLCWitness;
  44. pub use cdk::nuts::nut15::{Mpp, MppMethodSettings};
  45. pub use cdk::nuts::{nut04, nut05, nut15, MeltQuoteState, MintQuoteState};
  46. }
  47. #[cfg(feature = "swagger")]
  48. use swagger_imports::*;
  49. /// CDK Mint State
  50. #[derive(Clone)]
  51. pub struct MintState {
  52. mint: Arc<Mint>,
  53. cache: Arc<cache::HttpCache>,
  54. }
  55. #[cfg(feature = "swagger")]
  56. #[derive(utoipa::OpenApi)]
  57. #[openapi(
  58. components(schemas(
  59. Amount,
  60. BlindedMessage,
  61. BlindSignature,
  62. BlindSignatureDleq,
  63. CheckStateRequest,
  64. CheckStateResponse,
  65. ContactInfo,
  66. CurrencyUnit,
  67. ErrorCode,
  68. ErrorResponse,
  69. HTLCWitness,
  70. Keys,
  71. KeysResponse,
  72. KeysetResponse,
  73. KeySet,
  74. KeySetInfo,
  75. MeltBolt11Request<String>,
  76. MeltQuoteBolt11Request,
  77. MeltQuoteBolt11Response<String>,
  78. MeltQuoteState,
  79. MeltMethodSettings,
  80. MintBolt11Request<String>,
  81. MintBolt11Response,
  82. MintInfo,
  83. MintQuoteBolt11Request,
  84. MintQuoteBolt11Response<String>,
  85. MintQuoteState,
  86. MintMethodSettings,
  87. MintVersion,
  88. Mpp,
  89. MppMethodSettings,
  90. Nuts,
  91. P2PKWitness,
  92. PaymentMethod,
  93. Proof,
  94. ProofDleq,
  95. ProofState,
  96. PublicKey,
  97. RestoreRequest,
  98. RestoreResponse,
  99. SecretKey,
  100. State,
  101. SupportedSettings,
  102. SwapRequest,
  103. SwapResponse,
  104. Witness,
  105. nut04::Settings,
  106. nut05::Settings,
  107. nut15::Settings
  108. )),
  109. info(description = "Cashu CDK mint APIs", title = "cdk-mintd",),
  110. paths(
  111. get_keys,
  112. get_keyset_pubkeys,
  113. get_keysets,
  114. get_mint_info,
  115. post_mint_bolt11_quote,
  116. get_check_mint_bolt11_quote,
  117. post_mint_bolt11,
  118. post_melt_bolt11_quote,
  119. get_check_melt_bolt11_quote,
  120. post_melt_bolt11,
  121. post_swap,
  122. post_check,
  123. post_restore
  124. )
  125. )]
  126. /// OpenAPI spec for the mint's v1 APIs
  127. pub struct ApiDocV1;
  128. /// Create mint [`Router`] with required endpoints for cashu mint with the default cache
  129. pub async fn create_mint_router(mint: Arc<Mint>) -> Result<Router> {
  130. create_mint_router_with_custom_cache(mint, Default::default()).await
  131. }
  132. async fn cors_middleware(
  133. req: axum::http::Request<axum::body::Body>,
  134. next: axum::middleware::Next,
  135. ) -> Response {
  136. // Handle preflight requests
  137. if req.method() == axum::http::Method::OPTIONS {
  138. let mut response = Response::new("".into());
  139. response
  140. .headers_mut()
  141. .insert("Access-Control-Allow-Origin", "*".parse().unwrap());
  142. response.headers_mut().insert(
  143. "Access-Control-Allow-Methods",
  144. "GET, POST, OPTIONS".parse().unwrap(),
  145. );
  146. response.headers_mut().insert(
  147. "Access-Control-Allow-Headers",
  148. "Content-Type".parse().unwrap(),
  149. );
  150. return response;
  151. }
  152. // Call the next handler
  153. let mut response = next.run(req).await;
  154. response
  155. .headers_mut()
  156. .insert("Access-Control-Allow-Origin", "*".parse().unwrap());
  157. response.headers_mut().insert(
  158. "Access-Control-Allow-Methods",
  159. "GET, POST, OPTIONS".parse().unwrap(),
  160. );
  161. response.headers_mut().insert(
  162. "Access-Control-Allow-Headers",
  163. "Content-Type".parse().unwrap(),
  164. );
  165. response
  166. }
  167. /// Create mint [`Router`] with required endpoints for cashu mint with a custom
  168. /// backend for cache
  169. pub async fn create_mint_router_with_custom_cache(
  170. mint: Arc<Mint>,
  171. cache: HttpCache,
  172. ) -> Result<Router> {
  173. let state = MintState {
  174. mint,
  175. cache: Arc::new(cache),
  176. };
  177. let v1_router = Router::new()
  178. .route("/keys", get(get_keys))
  179. .route("/keysets", get(get_keysets))
  180. .route("/keys/{keyset_id}", get(get_keyset_pubkeys))
  181. .route("/swap", post(cache_post_swap))
  182. .route("/mint/quote/bolt11", post(post_mint_bolt11_quote))
  183. .route(
  184. "/mint/quote/bolt11/{quote_id}",
  185. get(get_check_mint_bolt11_quote),
  186. )
  187. .route("/mint/bolt11", post(cache_post_mint_bolt11))
  188. .route("/melt/quote/bolt11", post(post_melt_bolt11_quote))
  189. .route("/ws", get(ws_handler))
  190. .route(
  191. "/melt/quote/bolt11/{quote_id}",
  192. get(get_check_melt_bolt11_quote),
  193. )
  194. .route("/melt/bolt11", post(cache_post_melt_bolt11))
  195. .route("/checkstate", post(post_check))
  196. .route("/info", get(get_mint_info))
  197. .route("/restore", post(post_restore));
  198. let mint_router = Router::new()
  199. .nest("/v1", v1_router)
  200. .layer(from_fn(cors_middleware));
  201. #[cfg(feature = "auth")]
  202. let mint_router = {
  203. let auth_router = create_auth_router(state.clone());
  204. mint_router.nest("/v1", auth_router)
  205. };
  206. let mint_router = mint_router.with_state(state);
  207. Ok(mint_router)
  208. }