waves_rust/model/account/
public_key.rs1use crate::error::Error::InvalidBytesLength;
2use crate::error::{Error, Result};
3use crate::model::account::Address;
4use crate::model::ByteString;
5use crate::util::Base58;
6use std::fmt;
7
8#[derive(Clone, Eq, PartialEq, Hash)]
9pub struct PublicKey {
10 bytes: Vec<u8>,
11}
12
13impl fmt::Debug for PublicKey {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 write!(f, "PublicKey {{ {} }}", self.encoded())
16 }
17}
18
19impl std::str::FromStr for PublicKey {
20 type Err = Error;
21
22 fn from_str(base58string: &str) -> Result<PublicKey> {
23 let bytes = Base58::decode(base58string)?;
24 Ok(PublicKey { bytes })
25 }
26}
27
28impl PublicKey {
29 pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey> {
30 if bytes.len() != 32 {
31 Err(InvalidBytesLength {
32 expected_len: 32,
33 actual_len: bytes.len(),
34 })?;
35 }
36 Ok(PublicKey {
37 bytes: Vec::from(bytes),
38 })
39 }
40
41 pub fn from_string(base58string: &str) -> Result<PublicKey> {
42 let bytes = Base58::decode(base58string)?;
43 Ok(PublicKey { bytes })
44 }
45
46 pub fn address(&self, chain_id: u8) -> Result<Address> {
47 Address::from_public_key(chain_id, self)
48 }
49}
50
51impl ByteString for PublicKey {
52 fn bytes(&self) -> Vec<u8> {
53 self.bytes.clone()
54 }
55
56 fn encoded(&self) -> String {
57 Base58::encode(&self.bytes, false)
58 }
59
60 fn encoded_with_prefix(&self) -> String {
61 Base58::encode(&self.bytes, true)
62 }
63}
64
65impl TryFrom<&str> for PublicKey {
66 type Error = Error;
67
68 fn try_from(value: &str) -> Result<Self> {
69 PublicKey::from_string(value)
70 }
71}
72
73impl TryFrom<String> for PublicKey {
74 type Error = Error;
75
76 fn try_from(value: String) -> Result<Self> {
77 PublicKey::from_string(&value)
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use std::str::FromStr;
84
85 use crate::error::Error::InvalidBytesLength;
86 use crate::error::Result;
87 use crate::model::account::{PrivateKey, PublicKey};
88 use crate::model::ByteString;
89 use crate::util::{Base58, Crypto};
90
91 #[test]
92 fn test_public_key_from_bytes() -> Result<()> {
93 let seed_phrase = "blame vacant regret company chase trip grant funny brisk innocent";
94
95 let expected_public_key_from_nonce_0 = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB";
96 let expected_public_key_from_nonce_128 = "DTvCW1nzFr7mHrHkGf1apstRfwPp4yYL19YvjjLEAPBh";
97 let expected_public_key_from_nonce_255 = "esjbpqVWSg8iCaPYQA3SoxZo3oUkdRJSi9tKLoqKQoC";
98
99 assert_eq!(
100 PublicKey::from_bytes(&public_key_bytes(seed_phrase, 0))?.encoded(),
101 expected_public_key_from_nonce_0
102 );
103 assert_eq!(
104 PublicKey::from_bytes(&public_key_bytes(seed_phrase, 128))?.encoded(),
105 expected_public_key_from_nonce_128
106 );
107 assert_eq!(
108 PublicKey::from_bytes(&public_key_bytes(seed_phrase, 255))?.encoded(),
109 expected_public_key_from_nonce_255
110 );
111 Ok(())
112 }
113
114 fn public_key_bytes(seed_phrase: &str, nonce: u8) -> Vec<u8> {
115 let bytes = PrivateKey::from_seed(seed_phrase, nonce)
116 .expect("failed to get private ket from seed phrase")
117 .bytes();
118 println!("{}", Base58::encode(&bytes.to_vec(), false));
119 Crypto::get_public_key(&bytes)
120 }
121
122 #[test]
123 fn test_invalid_bytes_len_for_public_key() -> Result<()> {
124 let public_key = PublicKey::from_bytes(&[]);
125 match public_key {
126 Ok(_) => panic!("expected error"),
127 Err(err) => match err {
128 InvalidBytesLength { .. } => Ok(()),
129 _ => panic!("expected InvalidBytesLength error"),
130 },
131 }
132 }
133
134 #[test]
135 fn test_public_key_from_str() -> Result<()> {
136 let expected_str = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB";
137 let public_key: PublicKey = expected_str.try_into()?;
138 assert_eq!(expected_str, public_key.encoded());
139 Ok(())
140 }
141
142 #[test]
143 fn test_public_key_from_string() -> Result<()> {
144 let expected_string = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB".to_owned();
145 let public_key: PublicKey = expected_string.clone().try_into()?;
146 assert_eq!(expected_string, public_key.encoded());
147 Ok(())
148 }
149
150 #[test]
151 fn test_public_key_std_from_str() -> Result<()> {
152 let expected_string = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB".to_owned();
153 let public_key = PublicKey::from_str(&expected_string)?;
154 assert_eq!(expected_string, public_key.encoded());
155 Ok(())
156 }
157
158 #[test]
159 fn test_byte_string_for_public_key() -> Result<()> {
160 let public_key: PublicKey = "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB".try_into()?;
161 let expected_bytes = vec![
162 113, 40, 188, 13, 166, 104, 24, 229, 65, 157, 176, 205, 96, 187, 101, 62, 170, 97, 253,
163 32, 117, 73, 107, 139, 119, 67, 237, 157, 117, 22, 27, 36,
164 ];
165 assert_eq!(expected_bytes, public_key.bytes());
166 assert_eq!(
167 "8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB",
168 public_key.encoded()
169 );
170 assert_eq!(
171 "base58:8cj6YzvQPhSHGvnjupNTW8zrADTT8CMAAd2xTuej84gB",
172 public_key.encoded_with_prefix()
173 );
174 Ok(())
175 }
176}