cdk_common/wallet/saga/
issue.rs1use cashu::BlindedMessage;
4use serde::{Deserialize, Serialize};
5
6use crate::Error;
7
8#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum IssueSagaState {
12 SecretsPrepared,
14 MintRequested,
16}
17
18impl std::fmt::Display for IssueSagaState {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 IssueSagaState::SecretsPrepared => write!(f, "secrets_prepared"),
22 IssueSagaState::MintRequested => write!(f, "mint_requested"),
23 }
24 }
25}
26
27impl std::str::FromStr for IssueSagaState {
28 type Err = Error;
29 fn from_str(s: &str) -> Result<Self, Self::Err> {
30 match s {
31 "secrets_prepared" => Ok(IssueSagaState::SecretsPrepared),
32 "mint_requested" => Ok(IssueSagaState::MintRequested),
33 _ => Err(Error::InvalidOperationState),
34 }
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
40pub struct MintOperationData {
41 quote_id: String,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
48 quote_ids: Option<Vec<String>>,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub is_batch: Option<bool>,
55 pub amount: crate::Amount,
57 pub counter_start: Option<u32>,
59 pub counter_end: Option<u32>,
61 #[serde(default, skip_serializing_if = "Option::is_none")]
66 pub blinded_messages: Option<Vec<BlindedMessage>>,
67 #[serde(default, skip_serializing_if = "Option::is_none")]
69 pub batch_output_counts: Option<Vec<usize>>,
70 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub batch_quote_amounts: Option<Vec<crate::Amount>>,
73}
74
75impl MintOperationData {
76 pub fn new_single(
78 quote_id: String,
79 amount: crate::Amount,
80 counter_start: Option<u32>,
81 counter_end: Option<u32>,
82 blinded_messages: Option<Vec<BlindedMessage>>,
83 ) -> Self {
84 Self {
85 quote_ids: Some(vec![quote_id.clone()]),
86 quote_id,
87 is_batch: Some(false),
88 amount,
89 counter_start,
90 counter_end,
91 blinded_messages,
92 batch_output_counts: None,
93 batch_quote_amounts: None,
94 }
95 }
96
97 pub fn new_batch(
99 quote_ids: Vec<String>,
100 amount: crate::Amount,
101 counter_start: Option<u32>,
102 counter_end: Option<u32>,
103 blinded_messages: Option<Vec<BlindedMessage>>,
104 ) -> Self {
105 let quote_id = quote_ids.first().cloned().unwrap_or_default();
106
107 Self {
108 quote_id,
109 quote_ids: Some(quote_ids),
110 is_batch: Some(true),
111 amount,
112 counter_start,
113 counter_end,
114 blinded_messages,
115 batch_output_counts: None,
116 batch_quote_amounts: None,
117 }
118 }
119
120 pub fn new_partitioned_batch(
122 quote_ids: Vec<String>,
123 amount: crate::Amount,
124 counter_start: Option<u32>,
125 counter_end: Option<u32>,
126 blinded_messages: Option<Vec<BlindedMessage>>,
127 batch_output_counts: Vec<usize>,
128 batch_quote_amounts: Vec<crate::Amount>,
129 ) -> Self {
130 let quote_id = quote_ids.first().cloned().unwrap_or_default();
131
132 Self {
133 quote_id,
134 quote_ids: Some(quote_ids),
135 is_batch: Some(true),
136 amount,
137 counter_start,
138 counter_end,
139 blinded_messages,
140 batch_output_counts: Some(batch_output_counts),
141 batch_quote_amounts: Some(batch_quote_amounts),
142 }
143 }
144
145 pub fn primary_quote_id(&self) -> &str {
147 &self.quote_id
148 }
149
150 pub fn quote_ids(&self) -> Vec<String> {
154 if let Some(ref ids) = self.quote_ids {
155 ids.clone()
156 } else {
157 vec![self.quote_id.clone()]
158 }
159 }
160
161 pub fn is_batch(&self) -> bool {
163 self.is_batch.unwrap_or(false)
164 }
165}