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}