nut07.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //! NUT-07: Spendable Check
  2. //!
  3. //! <https://github.com/cashubtc/nuts/blob/main/07.md>
  4. use std::fmt;
  5. use std::str::FromStr;
  6. use serde::{Deserialize, Serialize};
  7. use thiserror::Error;
  8. use super::nut01::PublicKey;
  9. /// NUT07 Error
  10. #[derive(Debug, Error, PartialEq, Eq)]
  11. pub enum Error {
  12. /// Unknown State error
  13. #[error("Unknown state")]
  14. UnknownState,
  15. }
  16. /// State of Proof
  17. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
  18. #[serde(rename_all = "UPPERCASE")]
  19. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  20. pub enum State {
  21. /// Spent
  22. Spent,
  23. /// Unspent
  24. Unspent,
  25. /// Pending
  26. ///
  27. /// Currently being used in a transaction i.e. melt in progress
  28. Pending,
  29. /// Reserved
  30. ///
  31. /// Proof is reserved for future token creation
  32. Reserved,
  33. /// Pending spent (i.e., spent but not yet swapped by receiver)
  34. PendingSpent,
  35. }
  36. impl fmt::Display for State {
  37. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  38. let s = match self {
  39. Self::Spent => "SPENT",
  40. Self::Unspent => "UNSPENT",
  41. Self::Pending => "PENDING",
  42. Self::Reserved => "RESERVED",
  43. Self::PendingSpent => "PENDING_SPENT",
  44. };
  45. write!(f, "{}", s)
  46. }
  47. }
  48. impl FromStr for State {
  49. type Err = Error;
  50. fn from_str(state: &str) -> Result<Self, Self::Err> {
  51. match state {
  52. "SPENT" => Ok(Self::Spent),
  53. "UNSPENT" => Ok(Self::Unspent),
  54. "PENDING" => Ok(Self::Pending),
  55. "RESERVED" => Ok(Self::Reserved),
  56. "PENDING_SPENT" => Ok(Self::PendingSpent),
  57. _ => Err(Error::UnknownState),
  58. }
  59. }
  60. }
  61. /// Check spendable request [NUT-07]
  62. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  63. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  64. pub struct CheckStateRequest {
  65. /// Y's of the proofs to check
  66. #[serde(rename = "Ys")]
  67. #[cfg_attr(feature = "swagger", schema(value_type = Vec<String>, max_items = 1_000))]
  68. pub ys: Vec<PublicKey>,
  69. }
  70. /// Proof state [NUT-07]
  71. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  72. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  73. pub struct ProofState {
  74. /// Y of proof
  75. #[serde(rename = "Y")]
  76. #[cfg_attr(feature = "swagger", schema(value_type = String))]
  77. pub y: PublicKey,
  78. /// State of proof
  79. pub state: State,
  80. /// Witness data if it is supplied
  81. pub witness: Option<String>,
  82. }
  83. impl From<(PublicKey, State)> for ProofState {
  84. fn from(value: (PublicKey, State)) -> Self {
  85. Self {
  86. y: value.0,
  87. state: value.1,
  88. witness: None,
  89. }
  90. }
  91. }
  92. /// Check Spendable Response [NUT-07]
  93. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
  94. #[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
  95. pub struct CheckStateResponse {
  96. /// Proof states
  97. pub states: Vec<ProofState>,
  98. }