brk_core/structs/
addressbytes.rs

1use std::fmt;
2
3use bitcoin::{
4    Address, Network, ScriptBuf,
5    hex::{Case, DisplayHex},
6    opcodes,
7    script::Builder,
8};
9use derive_deref::{Deref, DerefMut};
10use serde::{Serialize, Serializer};
11use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
12
13use crate::Error;
14
15use super::Addresstype;
16
17#[derive(Debug, PartialEq, Eq)]
18pub enum Addressbytes {
19    P2PK65(P2PK65AddressBytes),
20    P2PK33(P2PK33AddressBytes),
21    P2PKH(P2PKHAddressBytes),
22    P2SH(P2SHAddressBytes),
23    P2WPKH(P2WPKHAddressBytes),
24    P2WSH(P2WSHAddressBytes),
25    P2TR(P2TRAddressBytes),
26}
27
28impl Addressbytes {
29    pub fn as_slice(&self) -> &[u8] {
30        match self {
31            Addressbytes::P2PK65(bytes) => &bytes[..],
32            Addressbytes::P2PK33(bytes) => &bytes[..],
33            Addressbytes::P2PKH(bytes) => &bytes[..],
34            Addressbytes::P2SH(bytes) => &bytes[..],
35            Addressbytes::P2WPKH(bytes) => &bytes[..],
36            Addressbytes::P2WSH(bytes) => &bytes[..],
37            Addressbytes::P2TR(bytes) => &bytes[..],
38        }
39    }
40}
41
42impl TryFrom<(&ScriptBuf, Addresstype)> for Addressbytes {
43    type Error = Error;
44    fn try_from(tuple: (&ScriptBuf, Addresstype)) -> Result<Self, Self::Error> {
45        let (script, addresstype) = tuple;
46
47        match addresstype {
48            Addresstype::P2PK65 => {
49                let bytes = script.as_bytes();
50                let bytes = match bytes.len() {
51                    67 => &bytes[1..66],
52                    _ => {
53                        dbg!(bytes);
54                        return Err(Error::WrongLength);
55                    }
56                };
57                Ok(Self::P2PK65(P2PK65AddressBytes(U8x65::from(bytes))))
58            }
59            Addresstype::P2PK33 => {
60                let bytes = script.as_bytes();
61                let bytes = match bytes.len() {
62                    35 => &bytes[1..34],
63                    _ => {
64                        dbg!(bytes);
65                        return Err(Error::WrongLength);
66                    }
67                };
68                Ok(Self::P2PK33(P2PK33AddressBytes(U8x33::from(bytes))))
69            }
70            Addresstype::P2PKH => {
71                let bytes = &script.as_bytes()[3..23];
72                Ok(Self::P2PKH(P2PKHAddressBytes(U8x20::from(bytes))))
73            }
74            Addresstype::P2SH => {
75                let bytes = &script.as_bytes()[2..22];
76                Ok(Self::P2SH(P2SHAddressBytes(U8x20::from(bytes))))
77            }
78            Addresstype::P2WPKH => {
79                let bytes = &script.as_bytes()[2..];
80                Ok(Self::P2WPKH(P2WPKHAddressBytes(U8x20::from(bytes))))
81            }
82            Addresstype::P2WSH => {
83                let bytes = &script.as_bytes()[2..];
84                Ok(Self::P2WSH(P2WSHAddressBytes(U8x32::from(bytes))))
85            }
86            Addresstype::P2TR => {
87                let bytes = &script.as_bytes()[2..];
88                Ok(Self::P2TR(P2TRAddressBytes(U8x32::from(bytes))))
89            }
90            Addresstype::Multisig => Err(Error::WrongAddressType),
91            Addresstype::PushOnly => Err(Error::WrongAddressType),
92            Addresstype::Unknown => Err(Error::WrongAddressType),
93            Addresstype::Empty => Err(Error::WrongAddressType),
94            Addresstype::OpReturn => Err(Error::WrongAddressType),
95        }
96    }
97}
98
99#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
100pub struct P2PK65AddressBytes(U8x65);
101
102impl fmt::Display for P2PK65AddressBytes {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        write!(f, "{}", self.to_hex_string(Case::Lower))
105    }
106}
107
108impl Serialize for P2PK65AddressBytes {
109    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110    where
111        S: Serializer,
112    {
113        serializer.collect_str(&self.to_string())
114    }
115}
116
117impl From<P2PK65AddressBytes> for Addressbytes {
118    fn from(value: P2PK65AddressBytes) -> Self {
119        Self::P2PK65(value)
120    }
121}
122
123#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
124pub struct P2PK33AddressBytes(U8x33);
125
126impl fmt::Display for P2PK33AddressBytes {
127    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128        write!(f, "{}", self.to_hex_string(Case::Lower))
129    }
130}
131
132impl Serialize for P2PK33AddressBytes {
133    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
134    where
135        S: Serializer,
136    {
137        serializer.collect_str(&self.to_string())
138    }
139}
140
141impl From<P2PK33AddressBytes> for Addressbytes {
142    fn from(value: P2PK33AddressBytes) -> Self {
143        Self::P2PK33(value)
144    }
145}
146
147#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
148pub struct P2PKHAddressBytes(U8x20);
149
150impl fmt::Display for P2PKHAddressBytes {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        let script = Builder::new()
153            .push_opcode(opcodes::all::OP_DUP)
154            .push_opcode(opcodes::all::OP_HASH160)
155            .push_slice(*self.0)
156            .push_opcode(opcodes::all::OP_EQUALVERIFY)
157            .push_opcode(opcodes::all::OP_CHECKSIG)
158            .into_script();
159        let address = Address::from_script(&script, Network::Bitcoin).unwrap();
160        write!(f, "{}", address)
161    }
162}
163
164impl Serialize for P2PKHAddressBytes {
165    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
166    where
167        S: Serializer,
168    {
169        serializer.collect_str(&self.to_string())
170    }
171}
172
173impl From<P2PKHAddressBytes> for Addressbytes {
174    fn from(value: P2PKHAddressBytes) -> Self {
175        Self::P2PKH(value)
176    }
177}
178
179#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
180pub struct P2SHAddressBytes(U8x20);
181
182impl fmt::Display for P2SHAddressBytes {
183    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184        let script = Builder::new()
185            .push_opcode(opcodes::all::OP_HASH160)
186            .push_slice(*self.0)
187            .push_opcode(opcodes::all::OP_EQUAL)
188            .into_script();
189        let address = Address::from_script(&script, Network::Bitcoin).unwrap();
190        write!(f, "{}", address)
191    }
192}
193
194impl Serialize for P2SHAddressBytes {
195    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
196    where
197        S: Serializer,
198    {
199        serializer.collect_str(&self.to_string())
200    }
201}
202
203impl From<P2SHAddressBytes> for Addressbytes {
204    fn from(value: P2SHAddressBytes) -> Self {
205        Self::P2SH(value)
206    }
207}
208
209#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
210pub struct P2WPKHAddressBytes(U8x20);
211
212impl fmt::Display for P2WPKHAddressBytes {
213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214        let script = Builder::new().push_int(0).push_slice(*self.0).into_script();
215        let address = Address::from_script(&script, Network::Bitcoin).unwrap();
216        write!(f, "{}", address)
217    }
218}
219
220impl Serialize for P2WPKHAddressBytes {
221    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
222    where
223        S: Serializer,
224    {
225        serializer.collect_str(&self.to_string())
226    }
227}
228
229impl From<P2WPKHAddressBytes> for Addressbytes {
230    fn from(value: P2WPKHAddressBytes) -> Self {
231        Self::P2WPKH(value)
232    }
233}
234
235#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
236pub struct P2WSHAddressBytes(U8x32);
237
238impl fmt::Display for P2WSHAddressBytes {
239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
240        let script = Builder::new().push_int(0).push_slice(*self.0).into_script();
241        let address = Address::from_script(&script, Network::Bitcoin).unwrap();
242        write!(f, "{}", address)
243    }
244}
245
246impl Serialize for P2WSHAddressBytes {
247    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
248    where
249        S: Serializer,
250    {
251        serializer.collect_str(&self.to_string())
252    }
253}
254
255impl From<P2WSHAddressBytes> for Addressbytes {
256    fn from(value: P2WSHAddressBytes) -> Self {
257        Self::P2WSH(value)
258    }
259}
260
261#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
262pub struct P2TRAddressBytes(U8x32);
263
264impl fmt::Display for P2TRAddressBytes {
265    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266        let script = Builder::new().push_int(1).push_slice(*self.0).into_script();
267        let address = Address::from_script(&script, Network::Bitcoin).unwrap();
268        write!(f, "{}", address)
269    }
270}
271
272impl Serialize for P2TRAddressBytes {
273    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
274    where
275        S: Serializer,
276    {
277        serializer.collect_str(&self.to_string())
278    }
279}
280
281impl From<P2TRAddressBytes> for Addressbytes {
282    fn from(value: P2TRAddressBytes) -> Self {
283        Self::P2TR(value)
284    }
285}
286
287#[derive(
288    Debug,
289    Clone,
290    Deref,
291    DerefMut,
292    PartialEq,
293    Eq,
294    Immutable,
295    IntoBytes,
296    KnownLayout,
297    FromBytes,
298    Serialize,
299)]
300pub struct U8x20([u8; 20]);
301impl From<&[u8]> for U8x20 {
302    fn from(slice: &[u8]) -> Self {
303        let mut arr = [0; 20];
304        arr.copy_from_slice(slice);
305        Self(arr)
306    }
307}
308
309#[derive(
310    Debug,
311    Clone,
312    Deref,
313    DerefMut,
314    PartialEq,
315    Eq,
316    Immutable,
317    IntoBytes,
318    KnownLayout,
319    FromBytes,
320    Serialize,
321)]
322pub struct U8x32([u8; 32]);
323impl From<&[u8]> for U8x32 {
324    fn from(slice: &[u8]) -> Self {
325        let mut arr = [0; 32];
326        arr.copy_from_slice(slice);
327        Self(arr)
328    }
329}
330
331#[derive(
332    Debug,
333    Clone,
334    Deref,
335    DerefMut,
336    PartialEq,
337    Eq,
338    Immutable,
339    IntoBytes,
340    KnownLayout,
341    FromBytes,
342    Serialize,
343)]
344pub struct U8x33(#[serde(with = "serde_bytes")] [u8; 33]);
345impl From<&[u8]> for U8x33 {
346    fn from(slice: &[u8]) -> Self {
347        let mut arr = [0; 33];
348        arr.copy_from_slice(slice);
349        Self(arr)
350    }
351}
352
353#[derive(
354    Debug,
355    Clone,
356    Deref,
357    DerefMut,
358    PartialEq,
359    Eq,
360    Immutable,
361    IntoBytes,
362    KnownLayout,
363    FromBytes,
364    Serialize,
365)]
366pub struct U8x64(#[serde(with = "serde_bytes")] [u8; 64]);
367impl From<&[u8]> for U8x64 {
368    fn from(slice: &[u8]) -> Self {
369        let mut arr = [0; 64];
370        arr.copy_from_slice(slice);
371        Self(arr)
372    }
373}
374
375#[derive(
376    Debug,
377    Clone,
378    Deref,
379    DerefMut,
380    PartialEq,
381    Eq,
382    Immutable,
383    IntoBytes,
384    KnownLayout,
385    FromBytes,
386    Serialize,
387)]
388pub struct U8x65(#[serde(with = "serde_bytes")] [u8; 65]);
389impl From<&[u8]> for U8x65 {
390    fn from(slice: &[u8]) -> Self {
391        let mut arr = [0; 65];
392        arr.copy_from_slice(slice);
393        Self(arr)
394    }
395}