1use generic_array::{
2 sequence::Split,
3 typenum::{U12, U20},
4 GenericArray,
5};
6use serde::{Deserialize, Serialize};
7use sha3::{digest::Update, Digest, Keccak256};
8use umbral_pre::{serde_bytes, PublicKey};
9
10#[derive(PartialEq, Debug, Serialize, Deserialize, Copy, Clone, PartialOrd, Eq, Ord)]
17pub struct Address(#[serde(with = "serde_bytes::as_hex")] [u8; Address::SIZE]);
18
19impl Address {
20 pub const SIZE: usize = 20;
22
23 pub fn new(bytes: &[u8; Self::SIZE]) -> Self {
25 Self(*bytes)
26 }
27
28 pub(crate) fn from_public_key(pk: &PublicKey) -> Self {
29 let pk_bytes = pk.to_uncompressed_bytes();
32 let digest = Keccak256::new().chain(&pk_bytes[1..]).finalize();
33
34 let (_prefix, address): (GenericArray<u8, U12>, GenericArray<u8, U20>) = digest.split();
35
36 Self(address.into())
37 }
38}
39
40impl AsRef<[u8]> for Address {
41 fn as_ref(&self) -> &[u8] {
42 self.0.as_ref()
43 }
44}
45
46impl From<Address> for [u8; Address::SIZE] {
47 fn from(address: Address) -> [u8; Address::SIZE] {
48 address.0
49 }
50}