mod.rs 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. //! NUT-00: Notation and Models
  2. //!
  3. //! <https://github.com/cashubtc/nuts/blob/main/00.md>
  4. use std::cmp::Ordering;
  5. use std::collections::{HashMap, HashSet};
  6. use std::fmt;
  7. use std::hash::{Hash, Hasher};
  8. use std::str::FromStr;
  9. use std::string::FromUtf8Error;
  10. use serde::{de, Deserialize, Deserializer, Serialize};
  11. use thiserror::Error;
  12. use super::nut02::ShortKeysetId;
  13. #[cfg(feature = "wallet")]
  14. use super::nut10;
  15. #[cfg(feature = "wallet")]
  16. use super::nut11::SpendingConditions;
  17. #[cfg(feature = "wallet")]
  18. use crate::amount::FeeAndAmounts;
  19. #[cfg(feature = "wallet")]
  20. use crate::amount::SplitTarget;
  21. #[cfg(feature = "wallet")]
  22. use crate::dhke::blind_message;
  23. use crate::dhke::hash_to_curve;
  24. use crate::nuts::nut01::PublicKey;
  25. #[cfg(feature = "wallet")]
  26. use crate::nuts::nut01::SecretKey;
  27. use crate::nuts::nut11::{serde_p2pk_witness, P2PKWitness};
  28. use crate::nuts::nut12::BlindSignatureDleq;
  29. use crate::nuts::nut14::{serde_htlc_witness, HTLCWitness};
  30. use crate::nuts::{Id, ProofDleq};
  31. use crate::secret::Secret;
  32. use crate::Amount;
  33. pub mod token;
  34. pub use token::{Token, TokenV3, TokenV4};
  35. /// List of [Proof]
  36. pub type Proofs = Vec<Proof>;
  37. /// Utility methods for [Proofs]
  38. pub trait ProofsMethods {
  39. /// Count proofs by keyset
  40. fn count_by_keyset(&self) -> HashMap<Id, u64>;
  41. /// Sum proofs by keyset
  42. fn sum_by_keyset(&self) -> HashMap<Id, Amount>;
  43. /// Try to sum up the amounts of all [Proof]s
  44. fn total_amount(&self) -> Result<Amount, Error>;
  45. /// Try to fetch the pubkeys of all [Proof]s
  46. fn ys(&self) -> Result<Vec<PublicKey>, Error>;
  47. /// Create a copy of proofs without dleqs
  48. fn without_dleqs(&self) -> Proofs;
  49. }
  50. impl ProofsMethods for Proofs {
  51. fn count_by_keyset(&self) -> HashMap<Id, u64> {
  52. count_by_keyset(self.iter())
  53. }
  54. fn sum_by_keyset(&self) -> HashMap<Id, Amount> {
  55. sum_by_keyset(self.iter())
  56. }
  57. fn total_amount(&self) -> Result<Amount, Error> {
  58. total_amount(self.iter())
  59. }
  60. fn ys(&self) -> Result<Vec<PublicKey>, Error> {
  61. ys(self.iter())
  62. }
  63. fn without_dleqs(&self) -> Proofs {
  64. self.iter()
  65. .map(|p| {
  66. let mut p = p.clone();
  67. p.dleq = None;
  68. p
  69. })
  70. .collect()
  71. }
  72. }
  73. impl ProofsMethods for HashSet<Proof> {
  74. fn count_by_keyset(&self) -> HashMap<Id, u64> {
  75. count_by_keyset(self.iter())
  76. }
  77. fn sum_by_keyset(&self) -> HashMap<Id, Amount> {
  78. sum_by_keyset(self.iter())
  79. }
  80. fn total_amount(&self) -> Result<Amount, Error> {
  81. total_amount(self.iter())
  82. }
  83. fn ys(&self) -> Result<Vec<PublicKey>, Error> {
  84. ys(self.iter())
  85. }
  86. fn without_dleqs(&self) -> Proofs {
  87. self.iter()
  88. .map(|p| {
  89. let mut p = p.clone();
  90. p.dleq = None;
  91. p
  92. })
  93. .collect()
  94. }
  95. }
  96. fn count_by_keyset<'a, I: Iterator<Item = &'a Proof>>(proofs: I) -> HashMap<Id, u64> {
  97. let mut counts = HashMap::new();
  98. for proof in proofs {
  99. *counts.entry(proof.keyset_id).or_insert(0) += 1;
  100. }
  101. counts
  102. }
  103. fn sum_by_keyset<'a, I: Iterator<Item = &'a Proof>>(proofs: I) -> HashMap<Id, Amount> {
  104. let mut sums = HashMap::new();
  105. for proof in proofs {
  106. *sums.entry(proof.keyset_id).or_insert(Amount::ZERO) += proof.amount;
  107. }
  108. sums
  109. }
  110. fn total_amount<'a, I: Iterator<Item = &'a Proof>>(proofs: I) -> Result<Amount, Error> {
  111. Amount::try_sum(proofs.map(|p| p.amount)).map_err(Into::into)
  112. }
  113. fn ys<'a, I: Iterator<Item = &'a Proof>>(proofs: I) -> Result<Vec<PublicKey>, Error> {
  114. proofs.map(|p| p.y()).collect::<Result<Vec<PublicKey>, _>>()
  115. }
  116. /// NUT00 Error
  117. #[derive(Debug, Error)]
  118. pub enum Error {
  119. /// Proofs required
  120. #[error("Proofs required in token")]
  121. ProofsRequired,
  122. /// Unsupported token
  123. #[error("Unsupported token")]
  124. UnsupportedToken,
  125. /// Unsupported token
  126. #[error("Unsupported unit")]
  127. UnsupportedUnit,
  128. /// Unsupported token
  129. #[error("Unsupported payment method")]
  130. UnsupportedPaymentMethod,
  131. /// Duplicate proofs in token
  132. #[error("Duplicate proofs in token")]
  133. DuplicateProofs,
  134. /// Serde Json error
  135. #[error(transparent)]
  136. SerdeJsonError(#[from] serde_json::Error),
  137. /// Utf8 parse error
  138. #[error(transparent)]
  139. Utf8ParseError(#[from] FromUtf8Error),
  140. /// Base64 error
  141. #[error(transparent)]
  142. Base64Error(#[from] bitcoin::base64::DecodeError),
  143. /// Ciborium deserialization error
  144. #[error(transparent)]
  145. CiboriumError(#[from] ciborium::de::Error<std::io::Error>),
  146. /// Ciborium serialization error
  147. #[error(transparent)]
  148. CiboriumSerError(#[from] ciborium::ser::Error<std::io::Error>),
  149. /// Amount Error
  150. #[error(transparent)]
  151. Amount(#[from] crate::amount::Error),
  152. /// Secret error
  153. #[error(transparent)]
  154. Secret(#[from] crate::secret::Error),
  155. /// DHKE error
  156. #[error(transparent)]
  157. DHKE(#[from] crate::dhke::Error),
  158. /// NUT10 error
  159. #[error(transparent)]
  160. NUT10(#[from] crate::nuts::nut10::Error),
  161. /// NUT11 error
  162. #[error(transparent)]
  163. NUT11(#[from] crate::nuts::nut11::Error),
  164. /// Short keyset id -> id error
  165. #[error(transparent)]
  166. NUT02(#[from] crate::nuts::nut02::Error),
  167. }
  168. /// Blinded Message (also called `output`)
  169. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  170. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  171. pub struct BlindedMessage {
  172. /// Amount
  173. ///
  174. /// The value for the requested [BlindSignature]
  175. pub amount: Amount,
  176. /// Keyset ID
  177. ///
  178. /// ID from which we expect a signature.
  179. #[serde(rename = "id")]
  180. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  181. pub keyset_id: Id,
  182. /// Blinded secret message (B_)
  183. ///
  184. /// The blinded secret message generated by the sender.
  185. #[serde(rename = "B_")]
  186. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  187. pub blinded_secret: PublicKey,
  188. /// Witness
  189. ///
  190. /// <https://github.com/cashubtc/nuts/blob/main/11.md>
  191. #[serde(skip_serializing_if = "Option::is_none")]
  192. pub witness: Option<Witness>,
  193. }
  194. impl BlindedMessage {
  195. /// Compose new blinded message
  196. #[inline]
  197. pub fn new(amount: Amount, keyset_id: Id, blinded_secret: PublicKey) -> Self {
  198. Self {
  199. amount,
  200. keyset_id,
  201. blinded_secret,
  202. witness: None,
  203. }
  204. }
  205. /// Add witness
  206. #[inline]
  207. pub fn witness(&mut self, witness: Witness) {
  208. self.witness = Some(witness);
  209. }
  210. }
  211. /// Blind Signature (also called `promise`)
  212. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  213. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  214. pub struct BlindSignature {
  215. /// Amount
  216. ///
  217. /// The value of the blinded token.
  218. pub amount: Amount,
  219. /// Keyset ID
  220. ///
  221. /// ID of the mint keys that signed the token.
  222. #[serde(rename = "id")]
  223. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  224. pub keyset_id: Id,
  225. /// Blinded signature (C_)
  226. ///
  227. /// The blinded signature on the secret message `B_` of [BlindedMessage].
  228. #[serde(rename = "C_")]
  229. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  230. pub c: PublicKey,
  231. /// DLEQ Proof
  232. ///
  233. /// <https://github.com/cashubtc/nuts/blob/main/12.md>
  234. #[serde(skip_serializing_if = "Option::is_none")]
  235. pub dleq: Option<BlindSignatureDleq>,
  236. }
  237. impl Ord for BlindSignature {
  238. fn cmp(&self, other: &Self) -> Ordering {
  239. self.amount.cmp(&other.amount)
  240. }
  241. }
  242. impl PartialOrd for BlindSignature {
  243. fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  244. Some(self.cmp(other))
  245. }
  246. }
  247. /// Witness
  248. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  249. #[serde(untagged)]
  250. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  251. pub enum Witness {
  252. /// HTLC Witness
  253. #[serde(with = "serde_htlc_witness")]
  254. HTLCWitness(HTLCWitness),
  255. /// P2PK Witness
  256. #[serde(with = "serde_p2pk_witness")]
  257. P2PKWitness(P2PKWitness),
  258. }
  259. impl From<P2PKWitness> for Witness {
  260. fn from(witness: P2PKWitness) -> Self {
  261. Self::P2PKWitness(witness)
  262. }
  263. }
  264. impl From<HTLCWitness> for Witness {
  265. fn from(witness: HTLCWitness) -> Self {
  266. Self::HTLCWitness(witness)
  267. }
  268. }
  269. impl Witness {
  270. /// Add signatures to [`Witness`]
  271. pub fn add_signatures(&mut self, signatues: Vec<String>) {
  272. match self {
  273. Self::P2PKWitness(p2pk_witness) => p2pk_witness.signatures.extend(signatues),
  274. Self::HTLCWitness(htlc_witness) => match &mut htlc_witness.signatures {
  275. Some(sigs) => sigs.extend(signatues),
  276. None => htlc_witness.signatures = Some(signatues),
  277. },
  278. }
  279. }
  280. /// Get signatures on [`Witness`]
  281. pub fn signatures(&self) -> Option<Vec<String>> {
  282. match self {
  283. Self::P2PKWitness(witness) => Some(witness.signatures.clone()),
  284. Self::HTLCWitness(witness) => witness.signatures.clone(),
  285. }
  286. }
  287. /// Get preimage from [`Witness`]
  288. pub fn preimage(&self) -> Option<String> {
  289. match self {
  290. Self::P2PKWitness(_witness) => None,
  291. Self::HTLCWitness(witness) => Some(witness.preimage.clone()),
  292. }
  293. }
  294. }
  295. /// Proofs
  296. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  297. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  298. pub struct Proof {
  299. /// Amount
  300. pub amount: Amount,
  301. /// `Keyset id`
  302. #[serde(rename = "id")]
  303. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  304. pub keyset_id: Id,
  305. /// Secret message
  306. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  307. pub secret: Secret,
  308. /// Unblinded signature
  309. #[serde(rename = "C")]
  310. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  311. pub c: PublicKey,
  312. /// Witness
  313. #[serde(skip_serializing_if = "Option::is_none")]
  314. pub witness: Option<Witness>,
  315. /// DLEQ Proof
  316. #[serde(skip_serializing_if = "Option::is_none")]
  317. pub dleq: Option<ProofDleq>,
  318. }
  319. impl Proof {
  320. /// Create new [`Proof`]
  321. pub fn new(amount: Amount, keyset_id: Id, secret: Secret, c: PublicKey) -> Self {
  322. Proof {
  323. amount,
  324. keyset_id,
  325. secret,
  326. c,
  327. witness: None,
  328. dleq: None,
  329. }
  330. }
  331. /// Check if proof is in active keyset `Id`s
  332. pub fn is_active(&self, active_keyset_ids: &[Id]) -> bool {
  333. active_keyset_ids.contains(&self.keyset_id)
  334. }
  335. /// Get y from proof
  336. ///
  337. /// Where y is `hash_to_curve(secret)`
  338. pub fn y(&self) -> Result<PublicKey, Error> {
  339. Ok(hash_to_curve(self.secret.as_bytes())?)
  340. }
  341. }
  342. impl Hash for Proof {
  343. fn hash<H: Hasher>(&self, state: &mut H) {
  344. self.secret.hash(state);
  345. }
  346. }
  347. impl Ord for Proof {
  348. fn cmp(&self, other: &Self) -> std::cmp::Ordering {
  349. self.amount.cmp(&other.amount)
  350. }
  351. }
  352. impl PartialOrd for Proof {
  353. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  354. Some(self.cmp(other))
  355. }
  356. }
  357. /// Proof V4
  358. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  359. pub struct ProofV4 {
  360. /// Amount in satoshi
  361. #[serde(rename = "a")]
  362. pub amount: Amount,
  363. /// Secret message
  364. #[serde(rename = "s")]
  365. pub secret: Secret,
  366. /// Unblinded signature
  367. #[serde(
  368. serialize_with = "serialize_v4_pubkey",
  369. deserialize_with = "deserialize_v4_pubkey"
  370. )]
  371. pub c: PublicKey,
  372. /// Witness
  373. #[serde(default)]
  374. #[serde(skip_serializing_if = "Option::is_none")]
  375. pub witness: Option<Witness>,
  376. /// DLEQ Proof
  377. #[serde(rename = "d")]
  378. pub dleq: Option<ProofDleq>,
  379. }
  380. impl ProofV4 {
  381. /// [`ProofV4`] into [`Proof`]
  382. pub fn into_proof(&self, keyset_id: &Id) -> Proof {
  383. Proof {
  384. amount: self.amount,
  385. keyset_id: *keyset_id,
  386. secret: self.secret.clone(),
  387. c: self.c,
  388. witness: self.witness.clone(),
  389. dleq: self.dleq.clone(),
  390. }
  391. }
  392. }
  393. impl Hash for ProofV4 {
  394. fn hash<H: Hasher>(&self, state: &mut H) {
  395. self.secret.hash(state);
  396. }
  397. }
  398. impl From<Proof> for ProofV4 {
  399. fn from(proof: Proof) -> ProofV4 {
  400. let Proof {
  401. amount,
  402. keyset_id: _,
  403. secret,
  404. c,
  405. witness,
  406. dleq,
  407. } = proof;
  408. ProofV4 {
  409. amount,
  410. secret,
  411. c,
  412. witness,
  413. dleq,
  414. }
  415. }
  416. }
  417. impl From<ProofV3> for ProofV4 {
  418. fn from(proof: ProofV3) -> Self {
  419. Self {
  420. amount: proof.amount,
  421. secret: proof.secret,
  422. c: proof.c,
  423. witness: proof.witness,
  424. dleq: proof.dleq,
  425. }
  426. }
  427. }
  428. /// Proof v3 with short keyset id
  429. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  430. pub struct ProofV3 {
  431. /// Amount
  432. pub amount: Amount,
  433. /// Short keyset id
  434. #[serde(rename = "id")]
  435. pub keyset_id: ShortKeysetId,
  436. /// Secret message
  437. pub secret: Secret,
  438. /// Unblinded signature
  439. #[serde(rename = "C")]
  440. pub c: PublicKey,
  441. /// Witness
  442. #[serde(skip_serializing_if = "Option::is_none")]
  443. pub witness: Option<Witness>,
  444. /// DLEQ Proof
  445. #[serde(skip_serializing_if = "Option::is_none")]
  446. pub dleq: Option<ProofDleq>,
  447. }
  448. impl ProofV3 {
  449. /// [`ProofV3`] into [`Proof`]
  450. pub fn into_proof(&self, keyset_id: &Id) -> Proof {
  451. Proof {
  452. amount: self.amount,
  453. keyset_id: *keyset_id,
  454. secret: self.secret.clone(),
  455. c: self.c,
  456. witness: self.witness.clone(),
  457. dleq: self.dleq.clone(),
  458. }
  459. }
  460. }
  461. impl From<Proof> for ProofV3 {
  462. fn from(proof: Proof) -> ProofV3 {
  463. let Proof {
  464. amount,
  465. keyset_id,
  466. secret,
  467. c,
  468. witness,
  469. dleq,
  470. } = proof;
  471. ProofV3 {
  472. amount,
  473. secret,
  474. c,
  475. witness,
  476. dleq,
  477. keyset_id: keyset_id.into(),
  478. }
  479. }
  480. }
  481. impl Hash for ProofV3 {
  482. fn hash<H: Hasher>(&self, state: &mut H) {
  483. self.secret.hash(state);
  484. }
  485. }
  486. fn serialize_v4_pubkey<S>(key: &PublicKey, serializer: S) -> Result<S::Ok, S::Error>
  487. where
  488. S: serde::Serializer,
  489. {
  490. serializer.serialize_bytes(&key.to_bytes())
  491. }
  492. fn deserialize_v4_pubkey<'de, D>(deserializer: D) -> Result<PublicKey, D::Error>
  493. where
  494. D: serde::Deserializer<'de>,
  495. {
  496. let bytes = Vec::<u8>::deserialize(deserializer)?;
  497. PublicKey::from_slice(&bytes).map_err(serde::de::Error::custom)
  498. }
  499. /// Currency Unit
  500. #[non_exhaustive]
  501. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
  502. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  503. pub enum CurrencyUnit {
  504. /// Sat
  505. #[default]
  506. Sat,
  507. /// Msat
  508. Msat,
  509. /// Usd
  510. Usd,
  511. /// Euro
  512. Eur,
  513. /// Auth
  514. Auth,
  515. /// Custom currency unit
  516. Custom(String),
  517. }
  518. #[cfg(feature = "mint")]
  519. impl CurrencyUnit {
  520. /// Derivation index mint will use for unit
  521. pub fn derivation_index(&self) -> Option<u32> {
  522. match self {
  523. Self::Sat => Some(0),
  524. Self::Msat => Some(1),
  525. Self::Usd => Some(2),
  526. Self::Eur => Some(3),
  527. Self::Auth => Some(4),
  528. _ => None,
  529. }
  530. }
  531. }
  532. impl FromStr for CurrencyUnit {
  533. type Err = Error;
  534. fn from_str(value: &str) -> Result<Self, Self::Err> {
  535. let upper_value = value.to_uppercase();
  536. match upper_value.as_str() {
  537. "SAT" => Ok(Self::Sat),
  538. "MSAT" => Ok(Self::Msat),
  539. "USD" => Ok(Self::Usd),
  540. "EUR" => Ok(Self::Eur),
  541. "AUTH" => Ok(Self::Auth),
  542. _ => Ok(Self::Custom(value.to_string())),
  543. }
  544. }
  545. }
  546. impl fmt::Display for CurrencyUnit {
  547. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  548. let s = match self {
  549. CurrencyUnit::Sat => "SAT",
  550. CurrencyUnit::Msat => "MSAT",
  551. CurrencyUnit::Usd => "USD",
  552. CurrencyUnit::Eur => "EUR",
  553. CurrencyUnit::Auth => "AUTH",
  554. CurrencyUnit::Custom(unit) => unit,
  555. };
  556. if let Some(width) = f.width() {
  557. write!(f, "{:width$}", s.to_lowercase(), width = width)
  558. } else {
  559. write!(f, "{}", s.to_lowercase())
  560. }
  561. }
  562. }
  563. impl Serialize for CurrencyUnit {
  564. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  565. where
  566. S: serde::Serializer,
  567. {
  568. serializer.serialize_str(&self.to_string())
  569. }
  570. }
  571. impl<'de> Deserialize<'de> for CurrencyUnit {
  572. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  573. where
  574. D: Deserializer<'de>,
  575. {
  576. let currency: String = String::deserialize(deserializer)?;
  577. Self::from_str(&currency).map_err(|_| serde::de::Error::custom("Unsupported unit"))
  578. }
  579. }
  580. /// Payment Method
  581. #[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
  582. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  583. pub enum PaymentMethod {
  584. /// Bolt11 payment type
  585. #[default]
  586. Bolt11,
  587. /// Bolt12
  588. Bolt12,
  589. /// Custom
  590. Custom(String),
  591. }
  592. impl FromStr for PaymentMethod {
  593. type Err = Error;
  594. fn from_str(value: &str) -> Result<Self, Self::Err> {
  595. match value.to_lowercase().as_str() {
  596. "bolt11" => Ok(Self::Bolt11),
  597. "bolt12" => Ok(Self::Bolt12),
  598. c => Ok(Self::Custom(c.to_string())),
  599. }
  600. }
  601. }
  602. impl fmt::Display for PaymentMethod {
  603. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  604. match self {
  605. PaymentMethod::Bolt11 => write!(f, "bolt11"),
  606. PaymentMethod::Bolt12 => write!(f, "bolt12"),
  607. PaymentMethod::Custom(p) => write!(f, "{p}"),
  608. }
  609. }
  610. }
  611. impl Serialize for PaymentMethod {
  612. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  613. where
  614. S: serde::Serializer,
  615. {
  616. serializer.serialize_str(&self.to_string())
  617. }
  618. }
  619. impl<'de> Deserialize<'de> for PaymentMethod {
  620. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  621. where
  622. D: Deserializer<'de>,
  623. {
  624. let payment_method: String = String::deserialize(deserializer)?;
  625. Self::from_str(&payment_method).map_err(|_| de::Error::custom("Unsupported payment method"))
  626. }
  627. }
  628. /// PreMint
  629. #[cfg(feature = "wallet")]
  630. #[derive(Debug, Clone, PartialEq, Eq, Serialize)]
  631. pub struct PreMint {
  632. /// Blinded message
  633. pub blinded_message: BlindedMessage,
  634. /// Secret
  635. pub secret: Secret,
  636. /// R
  637. pub r: SecretKey,
  638. /// Amount
  639. pub amount: Amount,
  640. }
  641. #[cfg(feature = "wallet")]
  642. impl Ord for PreMint {
  643. fn cmp(&self, other: &Self) -> std::cmp::Ordering {
  644. self.amount.cmp(&other.amount)
  645. }
  646. }
  647. #[cfg(feature = "wallet")]
  648. impl PartialOrd for PreMint {
  649. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  650. Some(self.cmp(other))
  651. }
  652. }
  653. /// Premint Secrets
  654. #[cfg(feature = "wallet")]
  655. #[derive(Debug, Clone, PartialEq, Eq, Serialize)]
  656. pub struct PreMintSecrets {
  657. /// Secrets
  658. pub secrets: Vec<PreMint>,
  659. /// Keyset Id
  660. pub keyset_id: Id,
  661. }
  662. #[cfg(feature = "wallet")]
  663. impl PreMintSecrets {
  664. /// Create new [`PreMintSecrets`]
  665. pub fn new(keyset_id: Id) -> Self {
  666. Self {
  667. secrets: Vec::new(),
  668. keyset_id,
  669. }
  670. }
  671. /// Outputs for speceifed amount with random secret
  672. pub fn random(
  673. keyset_id: Id,
  674. amount: Amount,
  675. amount_split_target: &SplitTarget,
  676. fee_and_amounts: &FeeAndAmounts,
  677. ) -> Result<Self, Error> {
  678. let amount_split = amount.split_targeted(amount_split_target, fee_and_amounts)?;
  679. let mut output = Vec::with_capacity(amount_split.len());
  680. for amount in amount_split {
  681. let secret = Secret::generate();
  682. let (blinded, r) = blind_message(&secret.to_bytes(), None)?;
  683. let blinded_message = BlindedMessage::new(amount, keyset_id, blinded);
  684. output.push(PreMint {
  685. secret,
  686. blinded_message,
  687. r,
  688. amount,
  689. });
  690. }
  691. Ok(PreMintSecrets {
  692. secrets: output,
  693. keyset_id,
  694. })
  695. }
  696. /// Outputs from pre defined secrets
  697. pub fn from_secrets(
  698. keyset_id: Id,
  699. amounts: Vec<Amount>,
  700. secrets: Vec<Secret>,
  701. ) -> Result<Self, Error> {
  702. let mut output = Vec::with_capacity(secrets.len());
  703. for (secret, amount) in secrets.into_iter().zip(amounts) {
  704. let (blinded, r) = blind_message(&secret.to_bytes(), None)?;
  705. let blinded_message = BlindedMessage::new(amount, keyset_id, blinded);
  706. output.push(PreMint {
  707. secret,
  708. blinded_message,
  709. r,
  710. amount,
  711. });
  712. }
  713. Ok(PreMintSecrets {
  714. secrets: output,
  715. keyset_id,
  716. })
  717. }
  718. /// Blank Outputs used for NUT-08 change
  719. pub fn blank(keyset_id: Id, fee_reserve: Amount) -> Result<Self, Error> {
  720. let count = ((u64::from(fee_reserve) as f64).log2().ceil() as u64).max(1);
  721. let mut output = Vec::with_capacity(count as usize);
  722. for _i in 0..count {
  723. let secret = Secret::generate();
  724. let (blinded, r) = blind_message(&secret.to_bytes(), None)?;
  725. let blinded_message = BlindedMessage::new(Amount::ZERO, keyset_id, blinded);
  726. output.push(PreMint {
  727. secret,
  728. blinded_message,
  729. r,
  730. amount: Amount::ZERO,
  731. })
  732. }
  733. Ok(PreMintSecrets {
  734. secrets: output,
  735. keyset_id,
  736. })
  737. }
  738. /// Outputs with specific spending conditions
  739. pub fn with_conditions(
  740. keyset_id: Id,
  741. amount: Amount,
  742. amount_split_target: &SplitTarget,
  743. conditions: &SpendingConditions,
  744. fee_and_amounts: &FeeAndAmounts,
  745. ) -> Result<Self, Error> {
  746. let amount_split = amount.split_targeted(amount_split_target, fee_and_amounts)?;
  747. let mut output = Vec::with_capacity(amount_split.len());
  748. for amount in amount_split {
  749. let secret: nut10::Secret = conditions.clone().into();
  750. let secret: Secret = secret.try_into()?;
  751. let (blinded, r) = blind_message(&secret.to_bytes(), None)?;
  752. let blinded_message = BlindedMessage::new(amount, keyset_id, blinded);
  753. output.push(PreMint {
  754. secret,
  755. blinded_message,
  756. r,
  757. amount,
  758. });
  759. }
  760. Ok(PreMintSecrets {
  761. secrets: output,
  762. keyset_id,
  763. })
  764. }
  765. /// Iterate over secrets
  766. #[inline]
  767. pub fn iter(&self) -> impl Iterator<Item = &PreMint> {
  768. self.secrets.iter()
  769. }
  770. /// Length of secrets
  771. #[inline]
  772. pub fn len(&self) -> usize {
  773. self.secrets.len()
  774. }
  775. /// If secrets is empty
  776. #[inline]
  777. pub fn is_empty(&self) -> bool {
  778. self.secrets.is_empty()
  779. }
  780. /// Totoal amount of secrets
  781. pub fn total_amount(&self) -> Result<Amount, Error> {
  782. Ok(Amount::try_sum(
  783. self.secrets.iter().map(|PreMint { amount, .. }| *amount),
  784. )?)
  785. }
  786. /// [`BlindedMessage`]s from [`PreMintSecrets`]
  787. #[inline]
  788. pub fn blinded_messages(&self) -> Vec<BlindedMessage> {
  789. self.iter().map(|pm| pm.blinded_message.clone()).collect()
  790. }
  791. /// [`Secret`]s from [`PreMintSecrets`]
  792. #[inline]
  793. pub fn secrets(&self) -> Vec<Secret> {
  794. self.iter().map(|pm| pm.secret.clone()).collect()
  795. }
  796. /// Blinding factor from [`PreMintSecrets`]
  797. #[inline]
  798. pub fn rs(&self) -> Vec<SecretKey> {
  799. self.iter().map(|pm| pm.r.clone()).collect()
  800. }
  801. /// Amounts from [`PreMintSecrets`]
  802. #[inline]
  803. pub fn amounts(&self) -> Vec<Amount> {
  804. self.iter().map(|pm| pm.amount).collect()
  805. }
  806. /// Combine [`PreMintSecrets`]
  807. #[inline]
  808. pub fn combine(&mut self, mut other: Self) {
  809. self.secrets.append(&mut other.secrets)
  810. }
  811. /// Sort [`PreMintSecrets`] by [`Amount`]
  812. #[inline]
  813. pub fn sort_secrets(&mut self) {
  814. self.secrets.sort();
  815. }
  816. }
  817. // Implement Iterator for PreMintSecrets
  818. #[cfg(feature = "wallet")]
  819. impl Iterator for PreMintSecrets {
  820. type Item = PreMint;
  821. fn next(&mut self) -> Option<Self::Item> {
  822. // Use the iterator of the vector
  823. if self.secrets.is_empty() {
  824. return None;
  825. }
  826. Some(self.secrets.remove(0))
  827. }
  828. }
  829. #[cfg(feature = "wallet")]
  830. impl Ord for PreMintSecrets {
  831. fn cmp(&self, other: &Self) -> Ordering {
  832. self.secrets.cmp(&other.secrets)
  833. }
  834. }
  835. #[cfg(feature = "wallet")]
  836. impl PartialOrd for PreMintSecrets {
  837. fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  838. Some(self.cmp(other))
  839. }
  840. }
  841. #[cfg(test)]
  842. mod tests {
  843. use std::str::FromStr;
  844. use super::*;
  845. #[test]
  846. fn test_proof_serialize() {
  847. let proof = "[{\"id\":\"009a1f293253e41e\",\"amount\":2,\"secret\":\"407915bc212be61a77e3e6d2aeb4c727980bda51cd06a6afc29e2861768a7837\",\"C\":\"02bc9097997d81afb2cc7346b5e4345a9346bd2a506eb7958598a72f0cf85163ea\"},{\"id\":\"009a1f293253e41e\",\"amount\":8,\"secret\":\"fe15109314e61d7756b0f8ee0f23a624acaa3f4e042f61433c728c7057b931be\",\"C\":\"029e8e5050b890a7d6c0968db16bc1d5d5fa040ea1de284f6ec69d61299f671059\"}]";
  848. let proof: Proofs = serde_json::from_str(proof).unwrap();
  849. assert_eq!(
  850. proof[0].clone().keyset_id,
  851. Id::from_str("009a1f293253e41e").unwrap()
  852. );
  853. assert_eq!(proof.len(), 2);
  854. }
  855. #[test]
  856. #[cfg(feature = "wallet")]
  857. fn test_blank_blinded_messages() {
  858. let b = PreMintSecrets::blank(
  859. Id::from_str("009a1f293253e41e").unwrap(),
  860. Amount::from(1000),
  861. )
  862. .unwrap();
  863. assert_eq!(b.len(), 10);
  864. let b = PreMintSecrets::blank(Id::from_str("009a1f293253e41e").unwrap(), Amount::from(1))
  865. .unwrap();
  866. assert_eq!(b.len(), 1);
  867. }
  868. #[test]
  869. fn custom_unit_ser_der() {
  870. let unit = CurrencyUnit::Custom(String::from("test"));
  871. let serialized = serde_json::to_string(&unit).unwrap();
  872. let deserialized: CurrencyUnit = serde_json::from_str(&serialized).unwrap();
  873. assert_eq!(unit, deserialized)
  874. }
  875. #[test]
  876. fn test_payment_method_parsing() {
  877. // Test standard variants
  878. assert_eq!(
  879. PaymentMethod::from_str("bolt11").unwrap(),
  880. PaymentMethod::Bolt11
  881. );
  882. assert_eq!(
  883. PaymentMethod::from_str("BOLT11").unwrap(),
  884. PaymentMethod::Bolt11
  885. );
  886. assert_eq!(
  887. PaymentMethod::from_str("Bolt11").unwrap(),
  888. PaymentMethod::Bolt11
  889. );
  890. assert_eq!(
  891. PaymentMethod::from_str("bolt12").unwrap(),
  892. PaymentMethod::Bolt12
  893. );
  894. assert_eq!(
  895. PaymentMethod::from_str("BOLT12").unwrap(),
  896. PaymentMethod::Bolt12
  897. );
  898. assert_eq!(
  899. PaymentMethod::from_str("Bolt12").unwrap(),
  900. PaymentMethod::Bolt12
  901. );
  902. // Test custom variants
  903. assert_eq!(
  904. PaymentMethod::from_str("custom").unwrap(),
  905. PaymentMethod::Custom("custom".to_string())
  906. );
  907. assert_eq!(
  908. PaymentMethod::from_str("CUSTOM").unwrap(),
  909. PaymentMethod::Custom("custom".to_string())
  910. );
  911. // Test serialization/deserialization consistency
  912. let methods = vec![
  913. PaymentMethod::Bolt11,
  914. PaymentMethod::Bolt12,
  915. PaymentMethod::Custom("test".to_string()),
  916. ];
  917. for method in methods {
  918. let serialized = serde_json::to_string(&method).unwrap();
  919. let deserialized: PaymentMethod = serde_json::from_str(&serialized).unwrap();
  920. assert_eq!(method, deserialized);
  921. }
  922. }
  923. #[test]
  924. fn test_witness_serialization() {
  925. let htlc_witness = HTLCWitness {
  926. preimage: "preimage".to_string(),
  927. signatures: Some(vec!["sig1".to_string()]),
  928. };
  929. let witness = Witness::HTLCWitness(htlc_witness);
  930. let serialized = serde_json::to_string(&witness).unwrap();
  931. let deserialized: Witness = serde_json::from_str(&serialized).unwrap();
  932. assert!(matches!(deserialized, Witness::HTLCWitness(_)));
  933. let p2pk_witness = P2PKWitness {
  934. signatures: vec!["sig1".to_string(), "sig2".to_string()],
  935. };
  936. let witness = Witness::P2PKWitness(p2pk_witness);
  937. let serialized = serde_json::to_string(&witness).unwrap();
  938. let deserialized: Witness = serde_json::from_str(&serialized).unwrap();
  939. assert!(matches!(deserialized, Witness::P2PKWitness(_)));
  940. }
  941. }