1use gl_client::lnurl::models as wire;
9
10#[derive(Clone, uniffi::Record)]
18pub struct LnUrlPayRequestData {
19 pub callback: String,
21 pub min_sendable: u64,
23 pub max_sendable: u64,
25 pub metadata: String,
27 pub comment_allowed: u64,
29 pub description: String,
31 pub lnurl: String,
33}
34
35#[derive(Clone, uniffi::Record)]
41pub struct LnUrlWithdrawRequestData {
42 pub callback: String,
44 pub k1: String,
46 pub default_description: String,
48 pub min_withdrawable: u64,
50 pub max_withdrawable: u64,
52 pub lnurl: String,
54}
55
56#[derive(Clone, uniffi::Record)]
62pub struct LnUrlPayRequest {
63 pub data: LnUrlPayRequestData,
65 pub amount_msat: u64,
67 pub comment: Option<String>,
69 pub validate_success_action_url: Option<bool>,
78}
79
80#[derive(Clone, uniffi::Record)]
84pub struct LnUrlWithdrawRequest {
85 pub data: LnUrlWithdrawRequestData,
87 pub amount_msat: u64,
89 pub description: Option<String>,
91}
92
93#[derive(Clone, uniffi::Enum)]
97pub enum LnUrlPayResult {
98 EndpointSuccess { data: LnUrlPaySuccessData },
100 EndpointError { data: LnUrlErrorData },
102 PayError { data: LnUrlPayErrorData },
104}
105
106#[derive(Clone, uniffi::Record)]
108pub struct LnUrlPaySuccessData {
109 pub payment_preimage: String,
111 pub success_action: Option<SuccessActionProcessed>,
113}
114
115#[derive(Clone, uniffi::Record)]
117pub struct LnUrlPayErrorData {
118 pub payment_hash: String,
120 pub reason: String,
122}
123
124#[derive(Clone, uniffi::Enum)]
126pub enum LnUrlWithdrawResult {
127 Ok { data: LnUrlWithdrawSuccessData },
129 ErrorStatus { data: LnUrlErrorData },
131}
132
133#[derive(Clone, uniffi::Record)]
135pub struct LnUrlWithdrawSuccessData {
136 pub invoice: String,
138}
139
140#[derive(Clone, uniffi::Record)]
142pub struct LnUrlErrorData {
143 pub reason: String,
144}
145
146#[derive(Clone, uniffi::Enum)]
153pub enum SuccessActionProcessed {
154 Message { message: String },
156 Url { description: String, url: String },
158 Aes { description: String, plaintext: String },
160}
161
162impl From<wire::PayRequestResponse> for LnUrlPayRequestData {
165 fn from(r: wire::PayRequestResponse) -> Self {
166 Self {
167 description: r.description().unwrap_or_default(),
168 callback: r.callback,
169 min_sendable: r.min_sendable,
170 max_sendable: r.max_sendable,
171 metadata: r.metadata,
172 comment_allowed: r.comment_allowed.unwrap_or(0),
173 lnurl: String::new(), }
175 }
176}
177
178impl From<wire::WithdrawRequestResponse> for LnUrlWithdrawRequestData {
179 fn from(r: wire::WithdrawRequestResponse) -> Self {
180 Self {
181 callback: r.callback,
182 k1: r.k1,
183 default_description: r.default_description,
184 min_withdrawable: r.min_withdrawable,
185 max_withdrawable: r.max_withdrawable,
186 lnurl: String::new(), }
188 }
189}
190
191impl From<wire::ProcessedSuccessAction> for SuccessActionProcessed {
192 fn from(a: wire::ProcessedSuccessAction) -> Self {
193 match a {
194 wire::ProcessedSuccessAction::Message { message } => {
195 SuccessActionProcessed::Message { message }
196 }
197 wire::ProcessedSuccessAction::Url { description, url } => {
198 SuccessActionProcessed::Url { description, url }
199 }
200 wire::ProcessedSuccessAction::Aes {
201 description,
202 plaintext,
203 } => SuccessActionProcessed::Aes {
204 description,
205 plaintext,
206 },
207 }
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
216 fn test_pay_request_data_from_conversion() {
217 let wire_resp = wire::PayRequestResponse {
218 callback: "https://example.com/cb".to_string(),
219 max_sendable: 100000,
220 min_sendable: 1000,
221 tag: "payRequest".to_string(),
222 metadata: r#"[["text/plain", "Buy coffee"]]"#.to_string(),
223 comment_allowed: Some(140),
224 };
225
226 let data: LnUrlPayRequestData = wire_resp.into();
227 assert_eq!(data.callback, "https://example.com/cb");
228 assert_eq!(data.min_sendable, 1000);
229 assert_eq!(data.max_sendable, 100000);
230 assert_eq!(data.comment_allowed, 140);
231 assert_eq!(data.description, "Buy coffee");
232 assert!(data.lnurl.is_empty()); }
234
235 #[test]
236 fn test_pay_request_data_no_comment_allowed() {
237 let wire_resp = wire::PayRequestResponse {
238 callback: "https://example.com/cb".to_string(),
239 max_sendable: 100000,
240 min_sendable: 1000,
241 tag: "payRequest".to_string(),
242 metadata: r#"[["text/plain", "test"]]"#.to_string(),
243 comment_allowed: None,
244 };
245
246 let data: LnUrlPayRequestData = wire_resp.into();
247 assert_eq!(data.comment_allowed, 0);
248 }
249
250 #[test]
251 fn test_withdraw_request_data_from_conversion() {
252 let wire_resp = wire::WithdrawRequestResponse {
253 tag: "withdrawRequest".to_string(),
254 callback: "https://example.com/withdraw".to_string(),
255 k1: "secret123".to_string(),
256 default_description: "Withdraw from service".to_string(),
257 min_withdrawable: 1000,
258 max_withdrawable: 50000,
259 };
260
261 let data: LnUrlWithdrawRequestData = wire_resp.into();
262 assert_eq!(data.callback, "https://example.com/withdraw");
263 assert_eq!(data.k1, "secret123");
264 assert_eq!(data.default_description, "Withdraw from service");
265 assert_eq!(data.min_withdrawable, 1000);
266 assert_eq!(data.max_withdrawable, 50000);
267 }
268
269 #[test]
270 fn test_processed_success_action_from_message() {
271 let processed = wire::ProcessedSuccessAction::Message {
272 message: "Thanks!".to_string(),
273 };
274 let sdk: SuccessActionProcessed = processed.into();
275 match sdk {
276 SuccessActionProcessed::Message { message } => assert_eq!(message, "Thanks!"),
277 _ => panic!("Expected Message variant"),
278 }
279 }
280
281 #[test]
282 fn test_processed_success_action_from_url() {
283 let processed = wire::ProcessedSuccessAction::Url {
284 description: "View order".to_string(),
285 url: "https://example.com/order".to_string(),
286 };
287 let sdk: SuccessActionProcessed = processed.into();
288 match sdk {
289 SuccessActionProcessed::Url { description, url } => {
290 assert_eq!(description, "View order");
291 assert_eq!(url, "https://example.com/order");
292 }
293 _ => panic!("Expected Url variant"),
294 }
295 }
296
297 #[test]
298 fn test_processed_success_action_from_aes() {
299 let processed = wire::ProcessedSuccessAction::Aes {
300 description: "Your code".to_string(),
301 plaintext: "ABC-123".to_string(),
302 };
303 let sdk: SuccessActionProcessed = processed.into();
304 match sdk {
305 SuccessActionProcessed::Aes {
306 description,
307 plaintext,
308 } => {
309 assert_eq!(description, "Your code");
310 assert_eq!(plaintext, "ABC-123");
311 }
312 _ => panic!("Expected Aes variant"),
313 }
314 }
315}