1use serde::{Deserialize, Serialize};
2use thiserror::Error;
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
5#[macros::derive_from(breez_sdk_common::network::BitcoinNetwork)]
6#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
7pub enum BitcoinNetwork {
8 Bitcoin,
10 Testnet3,
11 Testnet4,
12 Signet,
13 Regtest,
14}
15
16#[derive(Clone, Debug, Error)]
17#[macros::derive_from(breez_sdk_common::input::ParseError)]
18pub enum ParseError {
19 #[error("empty input")]
20 EmptyInput,
21 #[error("Bip-21 error: {0}")]
22 Bip21Error(Bip21Error),
23 #[error("invalid input")]
24 InvalidInput,
25 #[error("Lnurl error: {0}")]
26 LnurlError(LnurlError),
27 #[error("Service connectivity error: {0}")]
28 ServiceConnectivity(ServiceConnectivityError),
29 #[error("Invalid external input parser: {0}")]
30 InvalidExternalInputParser(String),
31}
32
33#[derive(Clone, Debug, Error)]
34#[macros::derive_from(breez_sdk_common::input::Bip21Error)]
35pub enum Bip21Error {
36 #[error("bip21 contains invalid address")]
37 InvalidAddress,
38 #[error("bip21 contains invalid amount")]
39 InvalidAmount,
40 #[error("bip21 contains invalid parameter value for '{0}'")]
41 InvalidParameter(String),
42 #[error("bip21 parameter missing equals character")]
43 MissingEquals,
44 #[error("bip21 contains parameter '{0}' multiple times")]
45 MultipleParams(String),
46 #[error("bip21 contains unknown required parameter '{0}'")]
47 UnknownRequiredParameter(String),
48 #[error("bip21 does not contain any payment methods")]
49 NoPaymentMethods,
50}
51
52#[derive(Clone, Debug, Error)]
53#[macros::derive_from(breez_sdk_common::lnurl::error::LnurlError)]
54pub enum LnurlError {
55 #[error("lnurl missing k1 parameter")]
56 MissingK1,
57 #[error("lnurl contains invalid k1 parameter")]
58 InvalidK1,
59 #[error("lnurl contains unsupported action")]
60 UnsupportedAction,
61 #[error("lnurl missing domain")]
62 MissingDomain,
63 #[error("error calling lnurl endpoint: {0}")]
64 ServiceConnectivity(#[from] ServiceConnectivityError),
65 #[error("endpoint error: {0}")]
66 EndpointError(String),
67 #[error("lnurl has http scheme without onion domain")]
68 HttpSchemeWithoutOnionDomain,
69 #[error("lnurl has https scheme with onion domain")]
70 HttpsSchemeWithOnionDomain,
71 #[error("lnurl error: {0}")]
72 General(String),
73 #[error("lnurl has unknown scheme")]
74 UnknownScheme,
75 #[error("lnurl has invalid uri: {0}")]
76 InvalidUri(String),
77 #[error("lnurl has invalid invoice: {0}")]
78 InvalidInvoice(String),
79 #[error("lnurl has invalid response: {0}")]
80 InvalidResponse(String),
81}
82
83#[derive(Clone, Debug, Error)]
84#[macros::derive_from(breez_sdk_common::error::ServiceConnectivityError)]
85#[macros::derive_into(breez_sdk_common::error::ServiceConnectivityError)]
86#[cfg_attr(feature = "uniffi", derive(uniffi::Error))]
87pub enum ServiceConnectivityError {
88 #[error("Builder error: {0}")]
89 Builder(String),
90 #[error("Redirect error: {0}")]
91 Redirect(String),
92 #[error("Status error: {status} - {body}")]
93 Status { status: u16, body: String },
94 #[error("Timeout error: {0}")]
95 Timeout(String),
96 #[error("Request error: {0}")]
97 Request(String),
98 #[error("Connect error: {0}")]
99 Connect(String),
100 #[error("Body error: {0}")]
101 Body(String),
102 #[error("Decode error: {0}")]
103 Decode(String),
104 #[error("Json error: {0}")]
105 Json(String),
106 #[error("Other error: {0}")]
107 Other(String),
108}
109
110#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
111#[macros::derive_from(breez_sdk_common::input::Amount)]
112#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
113pub enum Amount {
114 Bitcoin {
115 amount_msat: u64,
116 },
117 Currency {
119 iso4217_code: String,
121 fractional_amount: u64,
123 },
124}
125
126#[derive(Clone, Debug, Default, Deserialize, Serialize)]
127#[macros::derive_from(breez_sdk_common::input::Bip21Details)]
128#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
129pub struct Bip21Details {
130 pub amount_sat: Option<u64>,
131 pub asset_id: Option<String>,
132 pub uri: String,
133 pub extras: Vec<Bip21Extra>,
134 pub label: Option<String>,
135 pub message: Option<String>,
136 pub payment_methods: Vec<InputType>,
137}
138
139#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
140#[macros::derive_from(breez_sdk_common::input::Bip21Extra)]
141#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
142pub struct Bip21Extra {
143 pub key: String,
144 pub value: String,
145}
146
147#[derive(Clone, Debug, Deserialize, Serialize)]
148#[macros::derive_from(breez_sdk_common::input::BitcoinAddressDetails)]
149#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
150pub struct BitcoinAddressDetails {
151 pub address: String,
152 pub network: BitcoinNetwork,
153 pub source: PaymentRequestSource,
154}
155
156#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
157#[macros::derive_from(breez_sdk_common::input::Bolt11Invoice)]
158#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
159pub struct Bolt11Invoice {
160 pub bolt11: String,
161 pub source: PaymentRequestSource,
162}
163
164#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
165#[macros::derive_from(breez_sdk_common::input::Bolt11RouteHint)]
166#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
167pub struct Bolt11RouteHint {
168 pub hops: Vec<Bolt11RouteHintHop>,
169}
170
171#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
172#[macros::derive_from(breez_sdk_common::input::Bolt11RouteHintHop)]
173#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
174pub struct Bolt11RouteHintHop {
175 pub src_node_id: String,
177 pub short_channel_id: String,
179 pub fees_base_msat: u32,
181 pub fees_proportional_millionths: u32,
182
183 pub cltv_expiry_delta: u16,
185 pub htlc_minimum_msat: Option<u64>,
187 pub htlc_maximum_msat: Option<u64>,
189}
190
191#[derive(Clone, Debug, Deserialize, Serialize)]
192#[macros::derive_from(breez_sdk_common::input::Bolt12Invoice)]
193#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
194pub struct Bolt12Invoice {
195 pub invoice: String,
196 pub source: PaymentRequestSource,
197}
198
199#[derive(Clone, Debug, Deserialize, Serialize)]
200#[macros::derive_from(breez_sdk_common::input::Bolt12InvoiceRequestDetails)]
201#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
202pub struct Bolt12InvoiceRequestDetails {
203 }
205
206#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
207#[macros::derive_from(breez_sdk_common::input::Bolt12OfferBlindedPath)]
208#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
209pub struct Bolt12OfferBlindedPath {
210 pub blinded_hops: Vec<String>,
211}
212
213#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
214#[macros::derive_from(breez_sdk_common::input::Bolt11InvoiceDetails)]
215#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
216pub struct Bolt11InvoiceDetails {
217 pub amount_msat: Option<u64>,
218 pub description: Option<String>,
219 pub description_hash: Option<String>,
220 pub expiry: u64,
221 pub invoice: Bolt11Invoice,
222 pub min_final_cltv_expiry_delta: u64,
223 pub network: BitcoinNetwork,
224 pub payee_pubkey: String,
225 pub payment_hash: String,
226 pub payment_secret: String,
227 pub routing_hints: Vec<Bolt11RouteHint>,
228 pub timestamp: u64,
229}
230
231#[derive(Clone, Debug, Deserialize, Serialize)]
232#[macros::derive_from(breez_sdk_common::input::Bolt12InvoiceDetails)]
233#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
234pub struct Bolt12InvoiceDetails {
235 pub amount_msat: u64,
236 pub invoice: Bolt12Invoice,
237}
238
239#[derive(Clone, Debug, Deserialize, Serialize)]
240#[macros::derive_from(breez_sdk_common::input::Bolt12Offer)]
241#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
242pub struct Bolt12Offer {
243 pub offer: String,
244 pub source: PaymentRequestSource,
245}
246
247#[derive(Clone, Debug, Deserialize, Serialize)]
248#[macros::derive_from(breez_sdk_common::input::Bolt12OfferDetails)]
249#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
250pub struct Bolt12OfferDetails {
251 pub absolute_expiry: Option<u64>,
252 pub chains: Vec<String>,
253 pub description: Option<String>,
254 pub issuer: Option<String>,
255 pub min_amount: Option<Amount>,
256 pub offer: Bolt12Offer,
257 pub paths: Vec<Bolt12OfferBlindedPath>,
258 pub signing_pubkey: Option<String>,
259}
260
261#[derive(Clone, Debug, Deserialize, Serialize)]
262#[macros::derive_from(breez_sdk_common::input::InputType)]
263#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
264pub enum InputType {
265 BitcoinAddress(BitcoinAddressDetails),
266 Bolt11Invoice(Bolt11InvoiceDetails),
267 Bolt12Invoice(Bolt12InvoiceDetails),
268 Bolt12Offer(Bolt12OfferDetails),
269 LightningAddress(LightningAddressDetails),
270 LnurlPay(LnurlPayRequestDetails),
271 SilentPaymentAddress(SilentPaymentAddressDetails),
272 LnurlAuth(LnurlAuthRequestDetails),
273 Url(String),
274 Bip21(Bip21Details),
275 Bolt12InvoiceRequest(Bolt12InvoiceRequestDetails),
276 LnurlWithdraw(LnurlWithdrawRequestDetails),
277 SparkAddress(SparkAddressDetails),
278 SparkInvoice(SparkInvoiceDetails),
279 CrossChainAddress(CrossChainAddressDetails),
280}
281
282#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
283#[macros::derive_from(breez_sdk_common::input::CrossChainAddressFamily)]
284#[macros::derive_into(breez_sdk_common::input::CrossChainAddressFamily)]
285#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
286#[serde(rename_all = "snake_case")]
287pub enum CrossChainAddressFamily {
288 Evm,
289 Solana,
290 Tron,
291}
292
293#[derive(Clone, Debug, Deserialize, Serialize)]
294#[macros::derive_from(breez_sdk_common::input::CrossChainAddressDetails)]
295#[macros::derive_into(breez_sdk_common::input::CrossChainAddressDetails)]
296#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
297pub struct CrossChainAddressDetails {
298 pub address: String,
299 pub address_family: CrossChainAddressFamily,
300 pub contract_address: Option<String>,
301 pub chain_id: Option<u64>,
302 pub amount: Option<u128>,
303}
304
305#[derive(Clone, Debug, Deserialize, Serialize)]
306#[macros::derive_from(breez_sdk_common::lnurl::pay::LnurlPayRequestDetails)]
307#[macros::derive_into(breez_sdk_common::lnurl::pay::LnurlPayRequestDetails)]
308#[serde(rename_all = "camelCase")]
309#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
310pub struct LnurlPayRequestDetails {
311 pub callback: String,
312 pub min_sendable: u64,
314 pub max_sendable: u64,
316 #[serde(rename(deserialize = "metadata"))]
319 pub metadata_str: String,
320 #[serde(default)]
324 pub comment_allowed: u16,
325
326 #[serde(skip)]
331 pub domain: String,
332
333 #[serde(skip)]
334 pub url: String,
335
336 #[serde(skip)]
338 pub address: Option<String>,
339
340 pub allows_nostr: Option<bool>,
344 pub nostr_pubkey: Option<String>,
350}
351
352#[derive(Clone, Debug, Deserialize, Serialize)]
358#[macros::derive_from(breez_sdk_common::lnurl::auth::LnurlAuthRequestDetails)]
359#[macros::derive_into(breez_sdk_common::lnurl::auth::LnurlAuthRequestDetails)]
360#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
361pub struct LnurlAuthRequestDetails {
362 pub k1: String,
364
365 pub action: Option<String>,
367
368 #[serde(skip_serializing, skip_deserializing)]
371 pub domain: String,
372
373 #[serde(skip_serializing, skip_deserializing)]
376 pub url: String,
377}
378
379#[derive(Clone, Debug, Deserialize, Serialize)]
381#[macros::derive_from(breez_sdk_common::lnurl::LnurlErrorDetails)]
382#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
383pub struct LnurlErrorDetails {
384 pub reason: String,
385}
386
387#[derive(Clone, Debug, Deserialize, Serialize)]
389#[macros::derive_from(breez_sdk_common::lnurl::LnurlCallbackStatus)]
390#[serde(rename_all = "UPPERCASE")]
391#[serde(tag = "status")]
392#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
393pub enum LnurlCallbackStatus {
394 Ok,
396 #[serde(rename = "ERROR")]
398 ErrorStatus {
399 #[serde(flatten)]
400 error_details: LnurlErrorDetails,
401 },
402}
403
404#[derive(Clone, Debug, Deserialize, Serialize)]
405#[macros::derive_from(breez_sdk_common::lnurl::withdraw::LnurlWithdrawRequestDetails)]
406#[macros::derive_into(breez_sdk_common::lnurl::withdraw::LnurlWithdrawRequestDetails)]
407#[serde(rename_all = "camelCase")]
408#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
409pub struct LnurlWithdrawRequestDetails {
410 pub callback: String,
411 pub k1: String,
412 pub default_description: String,
413 pub min_withdrawable: u64,
415 pub max_withdrawable: u64,
417 #[serde(default)]
422 #[cfg_attr(feature = "uniffi", uniffi(default = ""))]
423 pub url: String,
424}
425
426#[derive(Clone, Debug, Deserialize, Serialize)]
427#[macros::derive_from(breez_sdk_common::input::SparkAddressDetails)]
428#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
429pub struct SparkAddressDetails {
430 pub address: String,
432 pub identity_public_key: String,
434 pub network: BitcoinNetwork,
435 pub source: PaymentRequestSource,
436}
437
438#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
439#[macros::derive_from(breez_sdk_common::input::SparkInvoiceDetails)]
440#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
441pub struct SparkInvoiceDetails {
442 pub invoice: String,
444 pub identity_public_key: String,
446 pub network: BitcoinNetwork,
447 pub amount: Option<u128>,
449 pub token_identifier: Option<String>,
451 pub expiry_time: Option<u64>,
453 pub description: Option<String>,
455 pub sender_public_key: Option<String>,
457}
458
459#[derive(Clone, Debug, Deserialize, Serialize)]
460#[macros::derive_from(breez_sdk_common::input::LightningAddressDetails)]
461#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
462pub struct LightningAddressDetails {
463 pub address: String,
464 pub pay_request: LnurlPayRequestDetails,
465}
466
467#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
468#[macros::derive_from(breez_sdk_common::input::PaymentRequestSource)]
469#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
470pub struct PaymentRequestSource {
471 pub bip_21_uri: Option<String>,
472 pub bip_353_address: Option<String>,
473}
474
475#[derive(Clone, Debug, Deserialize, Serialize)]
476#[macros::derive_from(breez_sdk_common::input::SilentPaymentAddressDetails)]
477#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
478pub struct SilentPaymentAddressDetails {
479 pub address: String,
480 pub network: BitcoinNetwork,
481 pub source: PaymentRequestSource,
482}
483
484#[derive(Debug, Clone, Serialize)]
486#[macros::derive_from(breez_sdk_common::input::ExternalInputParser)]
487#[macros::derive_into(breez_sdk_common::input::ExternalInputParser)]
488#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
489pub struct ExternalInputParser {
490 pub provider_id: String,
492 pub input_regex: String,
494 pub parser_url: String,
497}
498
499#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
504#[macros::derive_from(breez_sdk_common::lnurl::pay::SuccessAction)]
505#[macros::derive_into(breez_sdk_common::lnurl::pay::SuccessAction)]
506#[serde(rename_all = "camelCase")]
507#[serde(tag = "tag")]
508#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
509pub enum SuccessAction {
510 Aes {
512 #[serde(flatten)]
513 data: AesSuccessActionData,
514 },
515
516 Message {
518 #[serde(flatten)]
519 data: MessageSuccessActionData,
520 },
521
522 Url {
524 #[serde(flatten)]
525 data: UrlSuccessActionData,
526 },
527}
528
529#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
533#[macros::derive_from(breez_sdk_common::lnurl::pay::SuccessActionProcessed)]
534#[macros::derive_into(breez_sdk_common::lnurl::pay::SuccessActionProcessed)]
535#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
536pub enum SuccessActionProcessed {
537 Aes { result: AesSuccessActionDataResult },
541
542 Message { data: MessageSuccessActionData },
544
545 Url { data: UrlSuccessActionData },
547}
548
549#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
553#[macros::derive_from(breez_sdk_common::lnurl::pay::AesSuccessActionData)]
554#[macros::derive_into(breez_sdk_common::lnurl::pay::AesSuccessActionData)]
555#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
556pub struct AesSuccessActionData {
557 pub description: String,
559
560 pub ciphertext: String,
562
563 pub iv: String,
565}
566
567#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
569#[macros::derive_from(breez_sdk_common::lnurl::pay::AesSuccessActionDataResult)]
570#[macros::derive_into(breez_sdk_common::lnurl::pay::AesSuccessActionDataResult)]
571#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
572pub enum AesSuccessActionDataResult {
573 Decrypted { data: AesSuccessActionDataDecrypted },
574 ErrorStatus { reason: String },
575}
576
577#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
579#[macros::derive_from(breez_sdk_common::lnurl::pay::AesSuccessActionDataDecrypted)]
580#[macros::derive_into(breez_sdk_common::lnurl::pay::AesSuccessActionDataDecrypted)]
581#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
582pub struct AesSuccessActionDataDecrypted {
583 pub description: String,
585
586 pub plaintext: String,
588}
589
590#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
591#[macros::derive_from(breez_sdk_common::lnurl::pay::MessageSuccessActionData)]
592#[macros::derive_into(breez_sdk_common::lnurl::pay::MessageSuccessActionData)]
593#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
594pub struct MessageSuccessActionData {
595 pub message: String,
596}
597
598#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
599#[macros::derive_from(breez_sdk_common::lnurl::pay::UrlSuccessActionData)]
600#[macros::derive_into(breez_sdk_common::lnurl::pay::UrlSuccessActionData)]
601#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
602pub struct UrlSuccessActionData {
603 pub description: String,
605
606 pub url: String,
608
609 pub matches_callback_domain: bool,
613}
614
615#[cfg(test)]
616mod tests {
617 use super::LnurlWithdrawRequestDetails;
618
619 #[test]
623 fn withdraw_details_deserialize_without_url() {
624 let details: LnurlWithdrawRequestDetails = serde_json::from_str(
625 r#"{
626 "callback": "https://service.com/cb",
627 "k1": "abc",
628 "defaultDescription": "d",
629 "minWithdrawable": 1000,
630 "maxWithdrawable": 2000
631 }"#,
632 )
633 .unwrap();
634 assert_eq!(details.url, "");
635 }
636}