1use std::{fmt::Display, str::FromStr, sync::Arc};
4
5use crate::LwkError;
6
7#[derive(uniffi::Object)]
12pub struct Bip21 {
13 inner: lwk_payment_instructions::Bip21,
14}
15
16impl Display for Bip21 {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 write!(f, "{}", self.inner)
19 }
20}
21
22impl From<lwk_payment_instructions::Bip21> for Bip21 {
23 fn from(inner: lwk_payment_instructions::Bip21) -> Self {
24 Self { inner }
25 }
26}
27
28#[uniffi::export]
29impl Bip21 {
30 #[uniffi::constructor]
32 pub fn new(s: &str) -> Result<Arc<Self>, LwkError> {
33 let inner = lwk_payment_instructions::Bip21::from_str(s)
34 .map_err(|e| LwkError::Generic { msg: e })?;
35 Ok(Arc::new(Self { inner }))
36 }
37
38 pub fn as_str(&self) -> String {
40 self.inner.as_str().to_string()
41 }
42
43 pub fn address(&self) -> Arc<crate::blockdata::address::BitcoinAddress> {
45 Arc::new(self.inner.address().into())
46 }
47
48 pub fn amount(&self) -> Option<u64> {
50 self.inner.amount()
51 }
52
53 pub fn label(&self) -> Option<String> {
55 self.inner.label()
56 }
57
58 pub fn message(&self) -> Option<String> {
60 self.inner.message()
61 }
62
63 #[cfg(feature = "lightning")]
65 pub fn lightning(&self) -> Option<Arc<crate::Bolt11Invoice>> {
66 self.inner
67 .lightning()
68 .and_then(|inv| crate::Bolt11Invoice::new(&inv.to_string()).ok())
69 }
70
71 pub fn offer(&self) -> Option<String> {
73 self.inner.offer().map(|o| o.to_string())
74 }
75
76 pub fn payjoin(&self) -> Option<String> {
78 self.inner.payjoin().map(|u| u.to_string())
79 }
80
81 pub fn payjoin_output_substitution(&self) -> bool {
83 self.inner.payjoin_output_substitution()
84 }
85
86 pub fn silent_payment_address(&self) -> Option<String> {
88 self.inner.silent_payment_address().map(|sp| sp.to_string())
89 }
90}