1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use std::fmt::Debug;

use crate::crypto::public_key::PublicKey;
use anyhow::Result;
use bech32::{FromBase32, ToBase32, Variant};
use serde::{
    de::{Deserialize, Deserializer},
    ser::{Serialize, Serializer},
};

#[derive(Clone)]
pub struct Address([u8; 32]);

impl Address {
    pub fn from_bytes(bytes: [u8; 32]) -> Self {
        Self(bytes)
    }

    pub fn to_bytes(&self) -> [u8; 32] {
        self.0
    }

    pub fn from_bech32_string(bech32: &str) -> Result<Self> {
        let (_, data, _) = bech32::decode(bech32)?;
        let data = Vec::<u8>::from_base32(&data)?;

        let mut bits: [u8; 32] = [0u8; 32];
        bits.copy_from_slice(&data);

        Ok(Self(bits))
    }

    pub fn to_bech32_string(&self) -> Result<String> {
        let address = bech32::encode("erd", self.0.to_base32(), Variant::Bech32)?;
        Ok(address)
    }

    pub fn is_valid(&self) -> bool {
        self.0.len() == 32
    }
}

impl<'a> From<&'a PublicKey> for Address {
    fn from(public_key: &PublicKey) -> Address {
        let bytes = public_key.to_bytes();

        let mut bits: [u8; 32] = [0u8; 32];
        bits.copy_from_slice(&bytes);

        Address(bits)
    }
}

impl ToString for Address {
    fn to_string(&self) -> String {
        self.to_bech32_string().unwrap()
    }
}

impl Debug for Address {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.to_bech32_string().unwrap().as_str())
    }
}

impl Default for Address {
    fn default() -> Self {
        Address::from_bytes([0u8; 32])
    }
}

impl Serialize for Address {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(self.to_bech32_string().unwrap().as_str())
    }
}

impl<'de> Deserialize<'de> for Address {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(Self::from_bech32_string(s.as_str()).unwrap())
    }
}

#[cfg(test)]
pub mod tests {
    use super::*;

    #[test]
    fn test_decode_address() {
        let addr = Address::from_bech32_string(
            "erd1qqqqqqqqqqqqqpgqyfjjn43spw7teklwtpz4x5waygq2mluyj9ts0mdwn6",
        )
        .unwrap();
        let encode = hex::encode(addr.to_bytes());
        assert_eq!(
            encode,
            "00000000000000000500226529d6300bbcbcdbee58455351dd2200adff849157"
        );
    }
}