nut03.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //! NUT-03: Swap
  2. //!
  3. //! <https://github.com/cashubtc/nuts/blob/main/03.md>
  4. use serde::{Deserialize, Serialize};
  5. use thiserror::Error;
  6. #[cfg(feature = "wallet")]
  7. use super::nut00::PreMintSecrets;
  8. use super::nut00::{BlindSignature, BlindedMessage, Proofs};
  9. use super::ProofsMethods;
  10. use crate::Amount;
  11. /// NUT03 Error
  12. #[derive(Debug, Error)]
  13. pub enum Error {
  14. /// DHKE error
  15. #[error(transparent)]
  16. DHKE(#[from] crate::dhke::Error),
  17. /// Amount Error
  18. #[error(transparent)]
  19. Amount(#[from] crate::amount::Error),
  20. }
  21. /// Preswap information
  22. #[cfg(feature = "wallet")]
  23. #[derive(Debug, Clone, PartialEq, Eq, Serialize)]
  24. pub struct PreSwap {
  25. /// Preswap mint secrets
  26. pub pre_mint_secrets: PreMintSecrets,
  27. /// Swap request
  28. pub swap_request: SwapRequest,
  29. /// Amount to increment keyset counter by
  30. pub derived_secret_count: u32,
  31. /// Fee amount
  32. pub fee: Amount,
  33. }
  34. /// Swap Request [NUT-03]
  35. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  36. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  37. pub struct SwapRequest {
  38. /// Proofs that are to be spent in a `Swap`
  39. #[cfg_attr(feature = "swagger", schema(value_type = Vec<crate::Proof>))]
  40. inputs: Proofs,
  41. /// Blinded Messages for Mint to sign
  42. outputs: Vec<BlindedMessage>,
  43. }
  44. impl SwapRequest {
  45. /// Create new [`SwapRequest`]
  46. pub fn new(inputs: Proofs, outputs: Vec<BlindedMessage>) -> Self {
  47. Self {
  48. inputs: inputs.without_dleqs(),
  49. outputs,
  50. }
  51. }
  52. /// Get inputs (proofs)
  53. pub fn inputs(&self) -> &Proofs {
  54. &self.inputs
  55. }
  56. /// Get outputs (blinded messages)
  57. pub fn outputs(&self) -> &Vec<BlindedMessage> {
  58. &self.outputs
  59. }
  60. /// Get mutable reference to outputs (blinded messages)
  61. pub fn outputs_mut(&mut self) -> &mut Vec<BlindedMessage> {
  62. &mut self.outputs
  63. }
  64. /// Total value of proofs in [`SwapRequest`]
  65. pub fn input_amount(&self) -> Result<Amount, Error> {
  66. Ok(Amount::try_sum(
  67. self.inputs.iter().map(|proof| proof.amount),
  68. )?)
  69. }
  70. /// Total value of outputs in [`SwapRequest`]
  71. pub fn output_amount(&self) -> Result<Amount, Error> {
  72. Ok(Amount::try_sum(
  73. self.outputs.iter().map(|proof| proof.amount),
  74. )?)
  75. }
  76. }
  77. /// Split Response [NUT-06]
  78. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  79. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  80. pub struct SwapResponse {
  81. /// Promises
  82. pub signatures: Vec<BlindSignature>,
  83. }
  84. impl SwapResponse {
  85. /// Create new [`SwapResponse`]
  86. pub fn new(promises: Vec<BlindSignature>) -> Self {
  87. Self {
  88. signatures: promises,
  89. }
  90. }
  91. /// Total [`Amount`] of promises
  92. pub fn promises_amount(&self) -> Result<Amount, Error> {
  93. Ok(Amount::try_sum(
  94. self.signatures
  95. .iter()
  96. .map(|BlindSignature { amount, .. }| *amount),
  97. )?)
  98. }
  99. }