1use crate::{LwkError, Script};
4use std::{fmt::Display, sync::Arc};
5
6#[derive(uniffi::Object)]
8#[uniffi::export(Display)]
9pub struct Address {
10 inner: elements::Address,
11}
12
13impl From<elements::Address> for Address {
14 fn from(inner: elements::Address) -> Self {
15 Self { inner }
16 }
17}
18
19impl AsRef<elements::Address> for Address {
20 fn as_ref(&self) -> &elements::Address {
21 &self.inner
22 }
23}
24
25impl From<Address> for elements::Address {
26 fn from(addr: Address) -> Self {
27 addr.inner
28 }
29}
30
31impl From<&Address> for elements::Address {
32 fn from(addr: &Address) -> Self {
33 addr.inner.clone()
34 }
35}
36
37impl Display for Address {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 write!(f, "{}", self.inner)
40 }
41}
42
43#[uniffi::export]
44impl Address {
45 #[uniffi::constructor]
47 pub fn new(s: &str) -> Result<Arc<Self>, LwkError> {
48 let inner: elements::Address = s.parse()?;
49 Ok(Arc::new(Self { inner }))
50 }
51
52 pub fn script_pubkey(&self) -> Arc<Script> {
54 Arc::new(self.inner.script_pubkey().into())
55 }
56
57 pub fn is_blinded(&self) -> bool {
59 self.inner.is_blinded()
60 }
61
62 pub fn to_unconfidential(&self) -> Arc<Self> {
64 Arc::new(self.inner.to_unconfidential().into())
65 }
66
67 pub fn qr_code_uri(&self, pixel_per_module: Option<u8>) -> Result<String, LwkError> {
75 Ok(lwk_common::address_to_uri_qr(
76 &self.inner,
77 pixel_per_module,
78 )?)
79 }
80
81 pub fn qr_code_text(&self) -> Result<String, LwkError> {
83 Ok(lwk_common::address_to_text_qr(&self.inner)?)
84 }
85}
86
87#[cfg(test)]
88mod tests {
89
90 use super::Address;
91
92 #[test]
93 fn address() {
94 let address_str = "tlq1qq2xvpcvfup5j8zscjq05u2wxxjcyewk7979f3mmz5l7uw5pqmx6xf5xy50hsn6vhkm5euwt72x878eq6zxx2z58hd7zrsg9qn";
95
96 let address = Address::new(address_str).unwrap();
97 assert_eq!(address.to_string(), address_str);
98
99 assert_eq!(
100 address.script_pubkey().to_string(),
101 "0014d0c4a3ef09e997b6e99e397e518fe3e41a118ca1"
102 );
103
104 assert!(address.is_blinded());
105
106 assert_eq!(
107 address.to_unconfidential().to_string(),
108 "tex1q6rz28mcfaxtmd6v789l9rrlrusdprr9p634wu8"
109 );
110
111 println!("{}", address.qr_code_text().unwrap());
112
113 let expected = "
114███████████████████████████████████████████████
115███████████████████████████████████████████████
116███ ▄▄▄▄▄ █▄▄▀▄▄▄▀▀▄█▀ ▀ ▀▀ █ █ █ ▄▄▄▄▄ ███
117███ █ █ █▀▀ ███▄██ ▄▀ ▀▄█▄█▄▄▀▀▀▄▄█ █ █ ███
118███ █▄▄▄█ █ █ ▄▄████▀█ ▀█▄▄▀▄█▀ ▀▀█ █▄▄▄█ ███
119███▄▄▄▄▄▄▄█ ▀▄▀ ▀ █▄█▄█ ▀ █▄█ █▄▀ █▄█▄▄▄▄▄▄▄███
120███▄▀█▀ █▄▄ █ ███▀█▀▄ ▄▄█▄▄▀█▄ █ █▄█▄▄▄ ▄██▄███
121███ ▀▄██ ▄▄▀█▀██▄ █▄▀▀▄ ▄▀▄ ▄▀ █ █▀█▄▀█▀▄███
122███▄ ▀▄█▄▄ █▀█ ▄▄▄█▀ █ ▄█▄█▀▄▀█▀█ ▀ ▀█▄ ▀ ▀███
123███▀ ▄▀▄▄██▄ █▄▀ █ ▀▀ ▄███▄▄▀█▄▄▀ ▀ █▀████
124███ █▀██▄▄▄▀ ▀▀▀█▄█▀███▄▄▀ ▄ ▄▀█▀▄▀▄▀▀▀█▀▀▀███
125███ █▄ ▄▄█▄█▄█▄██▀▄█▄▄▀ ▄▄ ▄█ ▀▀█ ██ █ ███
126███ █▄▄▀▄█ ▄ ▀▀▄▄▄ ▀▀█▀▀▀ ▀▄▀▄▀█▄▄█ █▄█▀ ▄▀███
127████ ▄▄█▄▄██▀▀ ▄ ▄▄▀██▄▄▀ ▄ █ ▄█▄▄█▄▄█ █ ███
128███▄▄ ▀▀█▄█▀█ █ ████ ██▄█ ▀▄▄█▀ ▄▀▄▄▀█▀▄▀▄▄▄███
129███▄▄█▄▀█▄▀ ▄▀▄█▀█ ▄ ▄███ ▄▄▄ █▀██▀ ▀ █ ████
130███ ▄▀█ █▄ █ █▀ ▀ █▄ █▀▀▄▀▄▄ ▄█▄ ▄ ▄██▄█▀▀▀████
131█████▄ ▄█▄▀ ▀ ▄▀▀▀▄█▄▀▄█▀ ▀ ▀ ▀▀ ▀█ ▄████
132███▄▄█▄▄█▄▄ ██ ▀ █ ██ █ █ ▄ █▀ ▀ ▀ ▄▄▄ ▀ ███
133███ ▄▄▄▄▄ █▄██▀█▄▀ ▀ ▀█▀█▀ ▄█▀█▄█▄█ █▄█ █▀▀███
134███ █ █ █▄▀█▀█▄ ▀█▀▄ █▀▄▄▄▄▄▄ ▀▀█ ▄ ▄███▄███
135███ █▄▄▄█ ██ ▀█▄ █▄▀█▄█▀▄██▀▄▄▀▄▀▄▀███▄ ███
136███▄▄▄▄▄▄▄█▄█▄█▄▄▄█▄▄█▄▄█▄▄███▄█▄█▄██▄█▄▄▄▄████
137███████████████████████████████████████████████";
138
139 assert!(address.qr_code_text().unwrap().contains(expected.trim()));
140
141 assert_eq!(address.qr_code_uri(None).unwrap(), "data:image/bmp;base64,Qk2GAQAAAAAAAD4AAAAoAAAAKQAAACkAAAABAAEAAAAAAEgBAAAAAgAAAAIAAAIAAAACAAAA////AAAAAAD+rtsVLwAAAIJnIiVDgAAAuk9JGoeAAAC6U1QO0AAAALqGM/j4gAAAghPrII2AAAD+hUGKrAAAAACdlV+PgAAA25WVyv2AAAAcfcT/9gAAAD62KlcnAAAAqV5aRQcAAADLSsXvkAAAAAmloRT9AAAA0tHx8G0AAAA4qEMaVAAAAOIoSs2LgAAAQHSHbAKAAAB2Hxvu2oAAAMS476hGgAAA2ueBU1MAAACYAQzPZYAAAL6ot+xlgAAAoPxBqruAAACHYQbxQAAAAOgn3wI9AAAAdmvTjNQAAABhUNCr54AAANceWkNNAAAAxKM3VqUAAACnB0+6iIAAAFiioJQIAAAAi6B7NXyAAAAA3g4mAAAAAP6qqqq/gAAAgrAuJ6CAAAC6vAzSLoAAALrgXA4ugAAAuiJqsa6AAACCIz/toIAAAP7clm2/gAAA");
142 }
143}