lib.rs 6.4 KB

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