types.rs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //! Types for `cashu-rs`
  2. use std::collections::HashMap;
  3. use bitcoin::Amount;
  4. use lightning_invoice::Invoice;
  5. use rand::Rng;
  6. use secp256k1::{PublicKey, SecretKey};
  7. use serde::{Deserialize, Deserializer, Serialize, Serializer};
  8. use crate::{dhke::blind_message, error::Error, utils::split_amount};
  9. /// Blinded Message [NUT-00]
  10. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  11. pub struct BlindedMessage {
  12. /// Amount in satoshi
  13. #[serde(with = "bitcoin::amount::serde::as_sat")]
  14. pub amount: Amount,
  15. /// encrypted secret message (B_)
  16. #[serde(rename = "B_")]
  17. pub b: PublicKey,
  18. }
  19. /// Blinded Messages [NUT-00]
  20. #[derive(Debug, Default, Clone, PartialEq, Eq)]
  21. pub struct BlindedMessages {
  22. /// Blinded messages
  23. pub blinded_messages: Vec<BlindedMessage>,
  24. /// Secrets
  25. pub secrets: Vec<Vec<u8>>,
  26. /// Rs
  27. pub rs: Vec<SecretKey>,
  28. /// Amounts
  29. pub amounts: Vec<Amount>,
  30. }
  31. impl BlindedMessages {
  32. pub fn random(amount: Amount) -> Result<Self, Error> {
  33. let mut blinded_messages = BlindedMessages::default();
  34. let mut rng = rand::thread_rng();
  35. for amount in split_amount(amount) {
  36. let bytes: [u8; 32] = rng.gen();
  37. let (blinded, r) = blind_message(&bytes, None)?;
  38. let blinded_message = BlindedMessage { amount, b: blinded };
  39. blinded_messages.secrets.push(bytes.to_vec());
  40. blinded_messages.blinded_messages.push(blinded_message);
  41. blinded_messages.rs.push(r);
  42. blinded_messages.amounts.push(amount);
  43. }
  44. Ok(blinded_messages)
  45. }
  46. }
  47. /// Promise (BlindedSignature) [NIP-00]
  48. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  49. pub struct Promise {
  50. pub id: String,
  51. #[serde(with = "bitcoin::amount::serde::as_sat")]
  52. pub amount: Amount,
  53. /// blinded signature (C_) on the secret message `B_` of [BlindedMessage]
  54. #[serde(rename = "C_")]
  55. pub c: String,
  56. }
  57. /// Proofs [NUT-00]
  58. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  59. pub struct Proof {
  60. /// Amount in satoshi
  61. #[serde(with = "bitcoin::amount::serde::as_sat")]
  62. pub amount: Amount,
  63. /// Secret message
  64. pub secret: String,
  65. /// Unblinded signature
  66. #[serde(rename = "C")]
  67. pub c: String,
  68. /// `Keyset id`
  69. pub id: Option<String>,
  70. /// P2SHScript that specifies the spending condition for this Proof
  71. pub script: Option<String>,
  72. }
  73. /// Mint Keys [NIP-01]
  74. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  75. pub struct MintKeys(pub HashMap<u64, String>);
  76. /// Mint Keysets [NIP-02]
  77. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  78. pub struct MintKeySets {
  79. /// set of public keys that the mint generates
  80. pub keysets: Vec<String>,
  81. }
  82. /// Mint request response [NUT-03]
  83. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  84. pub struct RequestMintResponse {
  85. /// Bolt11 payment request
  86. pub pr: Invoice,
  87. /// Hash of Invoice
  88. pub hash: String,
  89. }
  90. /// Post Mint Request [NIP-04]
  91. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  92. pub struct MintRequest {
  93. pub outputs: Vec<BlindedMessage>,
  94. }
  95. /// Post Mint Response [NUT-05]
  96. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  97. pub struct PostMintResponse {
  98. pub promises: Vec<Promise>,
  99. }
  100. /// Check Fees Response [NUT-05]
  101. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  102. pub struct CheckFeesResponse {
  103. /// Expected Mac Fee in satoshis
  104. #[serde(with = "bitcoin::amount::serde::as_sat")]
  105. pub fee: Amount,
  106. }
  107. /// Check Fees request [NUT-05]
  108. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  109. pub struct CheckFeesRequest {
  110. /// Lighting Invoice
  111. pub pr: Invoice,
  112. }
  113. /// Melt Request [NUT-05]
  114. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  115. pub struct MeltRequest {
  116. pub proofs: Vec<Proof>,
  117. /// bollt11
  118. pub pr: Invoice,
  119. /// Blinded Message that can be used to return change [NUT-08]
  120. /// Amount feild of blindedMessages `SHOULD` be set to zero
  121. pub outputs: Option<Vec<BlindedMessage>>,
  122. }
  123. /// Melt Response [NUT-05]
  124. /// Lightning fee return [NUT-08] if change is defined
  125. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  126. pub struct MeltResposne {
  127. pub paid: bool,
  128. pub preimage: String,
  129. pub change: Option<Promise>,
  130. }
  131. /// Split Request [NUT-06]
  132. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  133. pub struct SplitRequest {
  134. #[serde(with = "bitcoin::amount::serde::as_sat")]
  135. pub amount: Amount,
  136. pub proofs: Vec<Proof>,
  137. pub outputs: Vec<BlindedMessage>,
  138. }
  139. /// Split Response [NUT-06]
  140. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  141. pub struct SplitResponse {
  142. /// Promises to keep
  143. pub fst: Vec<BlindedMessage>,
  144. /// Promises to send
  145. pub snd: Vec<BlindedMessage>,
  146. }
  147. /// Check spendabale request [NUT-07]
  148. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  149. pub struct CheckSpendableRequest {
  150. pub proofs: Vec<Proof>,
  151. }
  152. /// Check Spendable Response [NUT-07]
  153. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  154. pub struct CheckSpendableResponse {
  155. /// booleans indicating whether the provided Proof is still spendable.
  156. /// In same order as provided proofs
  157. pub spendable: Vec<bool>,
  158. }
  159. /// Mint Version
  160. #[derive(Debug, Clone, PartialEq, Eq)]
  161. pub struct MintVersion {
  162. name: String,
  163. version: String,
  164. }
  165. impl Serialize for MintVersion {
  166. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  167. where
  168. S: Serializer,
  169. {
  170. let combined = format!("{}/{}", self.name, self.version);
  171. serializer.serialize_str(&combined)
  172. }
  173. }
  174. impl<'de> Deserialize<'de> for MintVersion {
  175. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  176. where
  177. D: Deserializer<'de>,
  178. {
  179. let combined = String::deserialize(deserializer)?;
  180. let parts: Vec<&str> = combined.split('/').collect();
  181. if parts.len() != 2 {
  182. return Err(serde::de::Error::custom("Invalid input string"));
  183. }
  184. Ok(MintVersion {
  185. name: parts[0].to_string(),
  186. version: parts[1].to_string(),
  187. })
  188. }
  189. }
  190. /// Mint Info [NIP-09]
  191. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  192. pub struct MintInfo {
  193. /// name of the mint and should be recognizable
  194. pub name: String,
  195. /// hex pubkey of the mint
  196. pub pubkey: String,
  197. /// implementation name and the version running
  198. pub version: MintVersion,
  199. /// short description of the mint
  200. pub description: String,
  201. /// long description
  202. pub description_long: String,
  203. /// contact methods to reach the mint operator
  204. pub contact: HashMap<String, String>,
  205. /// shows which NUTs the mint supports
  206. pub nuts: Vec<String>,
  207. /// message of the day that the wallet must display to the user
  208. pub motd: String,
  209. }