cdk_payment_processor/proto/
mod.rs1use std::str::FromStr;
2
3use cdk_common::payment::{
4 CreateIncomingPaymentResponse, MakePaymentResponse as CdkMakePaymentResponse,
5 PaymentIdentifier as CdkPaymentIdentifier, WaitPaymentResponse,
6};
7use cdk_common::{CurrencyUnit, MeltOptions as CdkMeltOptions};
8
9mod client;
10mod server;
11
12pub use client::PaymentProcessorClient;
13pub use server::PaymentProcessorServer;
14
15tonic::include_proto!("cdk_payment_processor");
16
17impl From<CdkPaymentIdentifier> for PaymentIdentifier {
18 fn from(value: CdkPaymentIdentifier) -> Self {
19 match value {
20 CdkPaymentIdentifier::Label(id) => Self {
21 r#type: PaymentIdentifierType::Label.into(),
22 value: Some(payment_identifier::Value::Id(id)),
23 },
24 CdkPaymentIdentifier::OfferId(id) => Self {
25 r#type: PaymentIdentifierType::OfferId.into(),
26 value: Some(payment_identifier::Value::Id(id)),
27 },
28 CdkPaymentIdentifier::PaymentHash(hash) => Self {
29 r#type: PaymentIdentifierType::PaymentHash.into(),
30 value: Some(payment_identifier::Value::Hash(hex::encode(hash))),
31 },
32 CdkPaymentIdentifier::Bolt12PaymentHash(hash) => Self {
33 r#type: PaymentIdentifierType::Bolt12PaymentHash.into(),
34 value: Some(payment_identifier::Value::Hash(hex::encode(hash))),
35 },
36 CdkPaymentIdentifier::CustomId(id) => Self {
37 r#type: PaymentIdentifierType::CustomId.into(),
38 value: Some(payment_identifier::Value::Id(id)),
39 },
40 CdkPaymentIdentifier::PaymentId(hash) => Self {
41 r#type: PaymentIdentifierType::PaymentId.into(),
42 value: Some(payment_identifier::Value::Hash(hex::encode(hash))),
43 },
44 }
45 }
46}
47
48impl TryFrom<PaymentIdentifier> for CdkPaymentIdentifier {
49 type Error = crate::error::Error;
50
51 fn try_from(value: PaymentIdentifier) -> Result<Self, Self::Error> {
52 match (value.r#type(), value.value) {
53 (PaymentIdentifierType::Label, Some(payment_identifier::Value::Id(id))) => {
54 Ok(CdkPaymentIdentifier::Label(id))
55 }
56 (PaymentIdentifierType::OfferId, Some(payment_identifier::Value::Id(id))) => {
57 Ok(CdkPaymentIdentifier::OfferId(id))
58 }
59 (PaymentIdentifierType::PaymentHash, Some(payment_identifier::Value::Hash(hash))) => {
60 let decoded = hex::decode(hash)?;
61 let hash_array: [u8; 32] = decoded
62 .try_into()
63 .map_err(|_| crate::error::Error::InvalidHash)?;
64 Ok(CdkPaymentIdentifier::PaymentHash(hash_array))
65 }
66 (
67 PaymentIdentifierType::Bolt12PaymentHash,
68 Some(payment_identifier::Value::Hash(hash)),
69 ) => {
70 let decoded = hex::decode(hash)?;
71 let hash_array: [u8; 32] = decoded
72 .try_into()
73 .map_err(|_| crate::error::Error::InvalidHash)?;
74 Ok(CdkPaymentIdentifier::Bolt12PaymentHash(hash_array))
75 }
76 (PaymentIdentifierType::CustomId, Some(payment_identifier::Value::Id(id))) => {
77 Ok(CdkPaymentIdentifier::CustomId(id))
78 }
79 _ => Err(crate::error::Error::InvalidPaymentIdentifier),
80 }
81 }
82}
83
84impl TryFrom<MakePaymentResponse> for CdkMakePaymentResponse {
85 type Error = crate::error::Error;
86 fn try_from(value: MakePaymentResponse) -> Result<Self, Self::Error> {
87 let status = value.status().as_str_name().parse()?;
88 let payment_proof = value.payment_proof;
89 let total_spent = value.total_spent.into();
90 let unit = CurrencyUnit::from_str(&value.unit)?;
91 let payment_identifier = value
92 .payment_identifier
93 .ok_or(crate::error::Error::InvalidPaymentIdentifier)?;
94 Ok(Self {
95 payment_lookup_id: payment_identifier.try_into()?,
96 payment_proof,
97 status,
98 total_spent,
99 unit,
100 })
101 }
102}
103
104impl From<CdkMakePaymentResponse> for MakePaymentResponse {
105 fn from(value: CdkMakePaymentResponse) -> Self {
106 Self {
107 payment_identifier: Some(value.payment_lookup_id.into()),
108 payment_proof: value.payment_proof,
109 status: QuoteState::from(value.status).into(),
110 total_spent: value.total_spent.into(),
111 unit: value.unit.to_string(),
112 }
113 }
114}
115
116impl From<CreateIncomingPaymentResponse> for CreatePaymentResponse {
117 fn from(value: CreateIncomingPaymentResponse) -> Self {
118 Self {
119 request_identifier: Some(value.request_lookup_id.into()),
120 request: value.request,
121 expiry: value.expiry,
122 }
123 }
124}
125
126impl TryFrom<CreatePaymentResponse> for CreateIncomingPaymentResponse {
127 type Error = crate::error::Error;
128
129 fn try_from(value: CreatePaymentResponse) -> Result<Self, Self::Error> {
130 let request_identifier = value
131 .request_identifier
132 .ok_or(crate::error::Error::InvalidPaymentIdentifier)?;
133 Ok(Self {
134 request_lookup_id: request_identifier.try_into()?,
135 request: value.request,
136 expiry: value.expiry,
137 })
138 }
139}
140
141impl From<cdk_common::payment::PaymentQuoteResponse> for PaymentQuoteResponse {
142 fn from(value: cdk_common::payment::PaymentQuoteResponse) -> Self {
143 Self {
144 request_identifier: value.request_lookup_id.map(|i| i.into()),
145 amount: value.amount.into(),
146 fee: value.fee.into(),
147 unit: value.unit.to_string(),
148 state: QuoteState::from(value.state).into(),
149 }
150 }
151}
152
153impl From<PaymentQuoteResponse> for cdk_common::payment::PaymentQuoteResponse {
154 fn from(value: PaymentQuoteResponse) -> Self {
155 let state_val = value.state();
156 let request_identifier = value.request_identifier;
157
158 Self {
159 request_lookup_id: request_identifier
160 .map(|i| i.try_into().expect("valid request identifier")),
161 amount: value.amount.into(),
162 fee: value.fee.into(),
163 unit: CurrencyUnit::from_str(&value.unit).unwrap_or_default(),
164 state: state_val.into(),
165 }
166 }
167}
168
169impl From<MeltOptions> for CdkMeltOptions {
170 fn from(value: MeltOptions) -> Self {
171 match value.options.expect("option defined") {
172 melt_options::Options::Mpp(mpp) => Self::Mpp {
173 mpp: cashu::nuts::nut15::Mpp {
174 amount: mpp.amount.into(),
175 },
176 },
177 melt_options::Options::Amountless(amountless) => Self::Amountless {
178 amountless: cashu::nuts::nut23::Amountless {
179 amount_msat: amountless.amount_msat.into(),
180 },
181 },
182 }
183 }
184}
185
186impl From<CdkMeltOptions> for MeltOptions {
187 fn from(value: CdkMeltOptions) -> Self {
188 match value {
189 CdkMeltOptions::Mpp { mpp } => Self {
190 options: Some(melt_options::Options::Mpp(Mpp {
191 amount: mpp.amount.into(),
192 })),
193 },
194 CdkMeltOptions::Amountless { amountless } => Self {
195 options: Some(melt_options::Options::Amountless(Amountless {
196 amount_msat: amountless.amount_msat.into(),
197 })),
198 },
199 }
200 }
201}
202
203impl From<QuoteState> for cdk_common::nuts::MeltQuoteState {
204 fn from(value: QuoteState) -> Self {
205 match value {
206 QuoteState::Unpaid => Self::Unpaid,
207 QuoteState::Paid => Self::Paid,
208 QuoteState::Pending => Self::Pending,
209 QuoteState::Unknown => Self::Unknown,
210 QuoteState::Failed => Self::Failed,
211 QuoteState::Issued => Self::Unknown,
212 }
213 }
214}
215
216impl From<cdk_common::nuts::MeltQuoteState> for QuoteState {
217 fn from(value: cdk_common::nuts::MeltQuoteState) -> Self {
218 match value {
219 cdk_common::nuts::MeltQuoteState::Unpaid => Self::Unpaid,
220 cdk_common::nuts::MeltQuoteState::Paid => Self::Paid,
221 cdk_common::nuts::MeltQuoteState::Pending => Self::Pending,
222 cdk_common::nuts::MeltQuoteState::Unknown => Self::Unknown,
223 cdk_common::nuts::MeltQuoteState::Failed => Self::Failed,
224 }
225 }
226}
227
228impl From<cdk_common::nuts::MintQuoteState> for QuoteState {
229 fn from(value: cdk_common::nuts::MintQuoteState) -> Self {
230 match value {
231 cdk_common::nuts::MintQuoteState::Unpaid => Self::Unpaid,
232 cdk_common::nuts::MintQuoteState::Paid => Self::Paid,
233 cdk_common::nuts::MintQuoteState::Issued => Self::Issued,
234 }
235 }
236}
237
238impl From<WaitPaymentResponse> for WaitIncomingPaymentResponse {
239 fn from(value: WaitPaymentResponse) -> Self {
240 Self {
241 payment_identifier: Some(value.payment_identifier.into()),
242 payment_amount: value.payment_amount.into(),
243 unit: value.unit.to_string(),
244 payment_id: value.payment_id,
245 }
246 }
247}
248
249impl TryFrom<WaitIncomingPaymentResponse> for WaitPaymentResponse {
250 type Error = crate::error::Error;
251
252 fn try_from(value: WaitIncomingPaymentResponse) -> Result<Self, Self::Error> {
253 let payment_identifier = value
254 .payment_identifier
255 .ok_or(crate::error::Error::InvalidPaymentIdentifier)?
256 .try_into()?;
257
258 Ok(Self {
259 payment_identifier,
260 payment_amount: value.payment_amount.into(),
261 unit: CurrencyUnit::from_str(&value.unit)?,
262 payment_id: value.payment_id,
263 })
264 }
265}