1use std::fmt;
2
3use bitcoin::{
4 Address, Network, ScriptBuf,
5 hex::{Case, DisplayHex},
6 opcodes,
7 script::Builder,
8};
9use brk_error::Error;
10use derive_deref::{Deref, DerefMut};
11use serde::{Serialize, Serializer};
12use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
13
14use super::OutputType;
15
16#[derive(Debug, PartialEq, Eq)]
17pub enum AddressBytes {
18 P2PK65(P2PK65Bytes),
19 P2PK33(P2PK33Bytes),
20 P2PKH(P2PKHBytes),
21 P2SH(P2SHBytes),
22 P2WPKH(P2WPKHBytes),
23 P2WSH(P2WSHBytes),
24 P2TR(P2TRBytes),
25 P2A(P2ABytes),
26}
27
28impl fmt::Display for AddressBytes {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 f.write_str(&match self {
31 AddressBytes::P2PK65(bytes) => bytes.to_string(),
32 AddressBytes::P2PK33(bytes) => bytes.to_string(),
33 AddressBytes::P2PKH(bytes) => bytes.to_string(),
34 AddressBytes::P2SH(bytes) => bytes.to_string(),
35 AddressBytes::P2WPKH(bytes) => bytes.to_string(),
36 AddressBytes::P2WSH(bytes) => bytes.to_string(),
37 AddressBytes::P2TR(bytes) => bytes.to_string(),
38 AddressBytes::P2A(bytes) => bytes.to_string(),
39 })
40 }
41}
42
43impl AddressBytes {
44 pub fn as_slice(&self) -> &[u8] {
45 match self {
46 AddressBytes::P2PK65(bytes) => &bytes[..],
47 AddressBytes::P2PK33(bytes) => &bytes[..],
48 AddressBytes::P2PKH(bytes) => &bytes[..],
49 AddressBytes::P2SH(bytes) => &bytes[..],
50 AddressBytes::P2WPKH(bytes) => &bytes[..],
51 AddressBytes::P2WSH(bytes) => &bytes[..],
52 AddressBytes::P2TR(bytes) => &bytes[..],
53 AddressBytes::P2A(bytes) => &bytes[..],
54 }
55 }
56}
57
58impl From<&Address> for AddressBytes {
59 fn from(value: &Address) -> Self {
60 Self::try_from((&value.script_pubkey(), OutputType::from(value))).unwrap()
61 }
62}
63
64impl TryFrom<(&ScriptBuf, OutputType)> for AddressBytes {
65 type Error = Error;
66 fn try_from(tuple: (&ScriptBuf, OutputType)) -> Result<Self, Self::Error> {
67 let (script, outputtype) = tuple;
68
69 match outputtype {
70 OutputType::P2PK65 => {
71 let bytes = script.as_bytes();
72 let bytes = match bytes.len() {
73 67 => &bytes[1..66],
74 _ => {
75 dbg!(bytes);
76 return Err(Error::WrongLength);
77 }
78 };
79 Ok(Self::P2PK65(P2PK65Bytes(U8x65::from(bytes))))
80 }
81 OutputType::P2PK33 => {
82 let bytes = script.as_bytes();
83 let bytes = match bytes.len() {
84 35 => &bytes[1..34],
85 _ => {
86 dbg!(bytes);
87 return Err(Error::WrongLength);
88 }
89 };
90 Ok(Self::P2PK33(P2PK33Bytes(U8x33::from(bytes))))
91 }
92 OutputType::P2PKH => {
93 let bytes = &script.as_bytes()[3..23];
94 Ok(Self::P2PKH(P2PKHBytes(U8x20::from(bytes))))
95 }
96 OutputType::P2SH => {
97 let bytes = &script.as_bytes()[2..22];
98 Ok(Self::P2SH(P2SHBytes(U8x20::from(bytes))))
99 }
100 OutputType::P2WPKH => {
101 let bytes = &script.as_bytes()[2..];
102 Ok(Self::P2WPKH(P2WPKHBytes(U8x20::from(bytes))))
103 }
104 OutputType::P2WSH => {
105 let bytes = &script.as_bytes()[2..];
106 Ok(Self::P2WSH(P2WSHBytes(U8x32::from(bytes))))
107 }
108 OutputType::P2TR => {
109 let bytes = &script.as_bytes()[2..];
110 Ok(Self::P2TR(P2TRBytes(U8x32::from(bytes))))
111 }
112 OutputType::P2A => {
113 let bytes = &script.as_bytes()[2..];
114 Ok(Self::P2A(P2ABytes(U8x2::from(bytes))))
115 }
116 OutputType::P2MS => Err(Error::WrongAddressType),
117 OutputType::Unknown => Err(Error::WrongAddressType),
118 OutputType::Empty => Err(Error::WrongAddressType),
119 OutputType::OpReturn => Err(Error::WrongAddressType),
120 _ => unreachable!(),
121 }
122 }
123}
124
125#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
126pub struct P2PK65Bytes(U8x65);
127
128impl fmt::Display for P2PK65Bytes {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 write!(f, "{}", self.to_hex_string(Case::Lower))
131 }
132}
133
134impl Serialize for P2PK65Bytes {
135 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136 where
137 S: Serializer,
138 {
139 serializer.collect_str(&self.to_string())
140 }
141}
142
143impl From<P2PK65Bytes> for AddressBytes {
144 fn from(value: P2PK65Bytes) -> Self {
145 Self::P2PK65(value)
146 }
147}
148
149#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
150pub struct P2PK33Bytes(U8x33);
151
152impl fmt::Display for P2PK33Bytes {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 write!(f, "{}", self.to_hex_string(Case::Lower))
155 }
156}
157
158impl Serialize for P2PK33Bytes {
159 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
160 where
161 S: Serializer,
162 {
163 serializer.collect_str(&self.to_string())
164 }
165}
166
167impl From<P2PK33Bytes> for AddressBytes {
168 fn from(value: P2PK33Bytes) -> Self {
169 Self::P2PK33(value)
170 }
171}
172
173#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
174pub struct P2PKHBytes(U8x20);
175
176impl fmt::Display for P2PKHBytes {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 let script = Builder::new()
179 .push_opcode(opcodes::all::OP_DUP)
180 .push_opcode(opcodes::all::OP_HASH160)
181 .push_slice(*self.0)
182 .push_opcode(opcodes::all::OP_EQUALVERIFY)
183 .push_opcode(opcodes::all::OP_CHECKSIG)
184 .into_script();
185 let address = Address::from_script(&script, Network::Bitcoin).unwrap();
186 write!(f, "{address}")
187 }
188}
189
190impl Serialize for P2PKHBytes {
191 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
192 where
193 S: Serializer,
194 {
195 serializer.collect_str(&self.to_string())
196 }
197}
198
199impl From<P2PKHBytes> for AddressBytes {
200 fn from(value: P2PKHBytes) -> Self {
201 Self::P2PKH(value)
202 }
203}
204
205#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
206pub struct P2SHBytes(U8x20);
207
208impl fmt::Display for P2SHBytes {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 let script = Builder::new()
211 .push_opcode(opcodes::all::OP_HASH160)
212 .push_slice(*self.0)
213 .push_opcode(opcodes::all::OP_EQUAL)
214 .into_script();
215 let address = Address::from_script(&script, Network::Bitcoin).unwrap();
216 write!(f, "{address}")
217 }
218}
219
220impl Serialize for P2SHBytes {
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<P2SHBytes> for AddressBytes {
230 fn from(value: P2SHBytes) -> Self {
231 Self::P2SH(value)
232 }
233}
234
235#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
236pub struct P2WPKHBytes(U8x20);
237
238impl fmt::Display for P2WPKHBytes {
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 P2WPKHBytes {
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<P2WPKHBytes> for AddressBytes {
256 fn from(value: P2WPKHBytes) -> Self {
257 Self::P2WPKH(value)
258 }
259}
260
261#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
262pub struct P2WSHBytes(U8x32);
263
264impl fmt::Display for P2WSHBytes {
265 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266 let script = Builder::new().push_int(0).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 P2WSHBytes {
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<P2WSHBytes> for AddressBytes {
282 fn from(value: P2WSHBytes) -> Self {
283 Self::P2WSH(value)
284 }
285}
286
287#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
288pub struct P2TRBytes(U8x32);
289
290impl fmt::Display for P2TRBytes {
291 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292 let script = Builder::new().push_int(1).push_slice(*self.0).into_script();
293 let address = Address::from_script(&script, Network::Bitcoin).unwrap();
294 write!(f, "{address}")
295 }
296}
297
298impl Serialize for P2TRBytes {
299 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
300 where
301 S: Serializer,
302 {
303 serializer.collect_str(&self.to_string())
304 }
305}
306
307impl From<P2TRBytes> for AddressBytes {
308 fn from(value: P2TRBytes) -> Self {
309 Self::P2TR(value)
310 }
311}
312
313#[derive(Debug, Clone, Deref, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
314pub struct P2ABytes(U8x2);
315
316impl fmt::Display for P2ABytes {
317 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318 let script = Builder::new().push_int(1).push_slice(*self.0).into_script();
319 let address = Address::from_script(&script, Network::Bitcoin).unwrap();
320 write!(f, "{address}")
321 }
322}
323
324impl Serialize for P2ABytes {
325 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
326 where
327 S: Serializer,
328 {
329 serializer.collect_str(&self.to_string())
330 }
331}
332
333impl From<P2ABytes> for AddressBytes {
334 fn from(value: P2ABytes) -> Self {
335 Self::P2A(value)
336 }
337}
338
339#[derive(
340 Debug,
341 Clone,
342 Deref,
343 DerefMut,
344 PartialEq,
345 Eq,
346 Immutable,
347 IntoBytes,
348 KnownLayout,
349 FromBytes,
350 Serialize,
351)]
352pub struct U8x2([u8; 2]);
353impl From<&[u8]> for U8x2 {
354 fn from(slice: &[u8]) -> Self {
355 let mut arr = [0; 2];
356 arr.copy_from_slice(slice);
357 Self(arr)
358 }
359}
360
361#[derive(
362 Debug,
363 Clone,
364 Deref,
365 DerefMut,
366 PartialEq,
367 Eq,
368 Immutable,
369 IntoBytes,
370 KnownLayout,
371 FromBytes,
372 Serialize,
373)]
374pub struct U8x20([u8; 20]);
375impl From<&[u8]> for U8x20 {
376 fn from(slice: &[u8]) -> Self {
377 let mut arr = [0; 20];
378 arr.copy_from_slice(slice);
379 Self(arr)
380 }
381}
382
383#[derive(
384 Debug,
385 Clone,
386 Deref,
387 DerefMut,
388 PartialEq,
389 Eq,
390 Immutable,
391 IntoBytes,
392 KnownLayout,
393 FromBytes,
394 Serialize,
395)]
396pub struct U8x32([u8; 32]);
397impl From<&[u8]> for U8x32 {
398 fn from(slice: &[u8]) -> Self {
399 let mut arr = [0; 32];
400 arr.copy_from_slice(slice);
401 Self(arr)
402 }
403}
404
405#[derive(
406 Debug,
407 Clone,
408 Deref,
409 DerefMut,
410 PartialEq,
411 Eq,
412 Immutable,
413 IntoBytes,
414 KnownLayout,
415 FromBytes,
416 Serialize,
417)]
418pub struct U8x33(#[serde(with = "serde_bytes")] [u8; 33]);
419impl From<&[u8]> for U8x33 {
420 fn from(slice: &[u8]) -> Self {
421 let mut arr = [0; 33];
422 arr.copy_from_slice(slice);
423 Self(arr)
424 }
425}
426
427#[derive(
428 Debug,
429 Clone,
430 Deref,
431 DerefMut,
432 PartialEq,
433 Eq,
434 Immutable,
435 IntoBytes,
436 KnownLayout,
437 FromBytes,
438 Serialize,
439)]
440pub struct U8x64(#[serde(with = "serde_bytes")] [u8; 64]);
441impl From<&[u8]> for U8x64 {
442 fn from(slice: &[u8]) -> Self {
443 let mut arr = [0; 64];
444 arr.copy_from_slice(slice);
445 Self(arr)
446 }
447}
448
449#[derive(
450 Debug,
451 Clone,
452 Deref,
453 DerefMut,
454 PartialEq,
455 Eq,
456 Immutable,
457 IntoBytes,
458 KnownLayout,
459 FromBytes,
460 Serialize,
461)]
462pub struct U8x65(#[serde(with = "serde_bytes")] [u8; 65]);
463impl From<&[u8]> for U8x65 {
464 fn from(slice: &[u8]) -> Self {
465 let mut arr = [0; 65];
466 arr.copy_from_slice(slice);
467 Self(arr)
468 }
469}