1#![forbid(unsafe_code)]
17
18use snarkvm::{
19 console::{network::prelude::*, types::Field},
20 prelude::*,
21};
22
23use colored::*;
24use core::fmt;
25
26#[derive(Clone, Debug)]
28pub struct Account<N: Network> {
29 private_key: PrivateKey<N>,
31 view_key: ViewKey<N>,
33 address: Address<N>,
35}
36
37impl<N: Network> Account<N> {
38 pub fn new<R: Rng + CryptoRng>(rng: &mut R) -> Result<Self> {
40 Self::try_from(PrivateKey::new(rng)?)
41 }
42
43 pub const fn private_key(&self) -> &PrivateKey<N> {
45 &self.private_key
46 }
47
48 pub const fn view_key(&self) -> &ViewKey<N> {
50 &self.view_key
51 }
52
53 pub const fn address(&self) -> Address<N> {
55 self.address
56 }
57}
58
59impl<N: Network> Account<N> {
60 pub fn sign<R: Rng + CryptoRng>(&self, message: &[Field<N>], rng: &mut R) -> Result<Signature<N>> {
62 Signature::sign(&self.private_key, message, rng)
63 }
64
65 pub fn sign_bytes<R: Rng + CryptoRng>(&self, message: &[u8], rng: &mut R) -> Result<Signature<N>> {
67 Signature::sign_bytes(&self.private_key, message, rng)
68 }
69
70 pub fn sign_bits<R: Rng + CryptoRng>(&self, message: &[bool], rng: &mut R) -> Result<Signature<N>> {
72 Signature::sign_bits(&self.private_key, message, rng)
73 }
74
75 pub fn verify(&self, message: &[Field<N>], signature: &Signature<N>) -> bool {
77 signature.verify(&self.address, message)
78 }
79
80 pub fn verify_bytes(&self, message: &[u8], signature: &Signature<N>) -> bool {
82 signature.verify_bytes(&self.address, message)
83 }
84
85 pub fn verify_bits(&self, message: &[bool], signature: &Signature<N>) -> bool {
87 signature.verify_bits(&self.address, message)
88 }
89}
90
91impl<N: Network> TryFrom<PrivateKey<N>> for Account<N> {
92 type Error = Error;
93
94 fn try_from(private_key: PrivateKey<N>) -> Result<Self, Self::Error> {
96 Self::try_from(&private_key)
97 }
98}
99
100impl<N: Network> TryFrom<&PrivateKey<N>> for Account<N> {
101 type Error = Error;
102
103 fn try_from(private_key: &PrivateKey<N>) -> Result<Self, Self::Error> {
105 let view_key = ViewKey::try_from(private_key)?;
106 let address = view_key.to_address();
107 Ok(Self { private_key: *private_key, view_key, address })
108 }
109}
110
111impl<N: Network> TryFrom<String> for Account<N> {
112 type Error = Error;
113
114 fn try_from(private_key: String) -> Result<Self, Self::Error> {
116 Self::try_from(&private_key)
117 }
118}
119
120impl<N: Network> TryFrom<&String> for Account<N> {
121 type Error = Error;
122
123 fn try_from(private_key: &String) -> Result<Self, Self::Error> {
125 Self::from_str(private_key.as_str())
126 }
127}
128
129impl<N: Network> TryFrom<&str> for Account<N> {
130 type Error = Error;
131
132 fn try_from(private_key: &str) -> Result<Self, Self::Error> {
134 Self::from_str(private_key)
135 }
136}
137
138impl<N: Network> FromStr for Account<N> {
139 type Err = Error;
140
141 fn from_str(private_key: &str) -> Result<Self, Self::Err> {
143 Self::try_from(PrivateKey::from_str(private_key)?)
144 }
145}
146
147impl<N: Network> Display for Account<N> {
148 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
150 write!(
151 f,
152 " {:>12} {}\n {:>12} {}\n {:>12} {}",
153 "Private Key".cyan().bold(),
154 self.private_key,
155 "View Key".cyan().bold(),
156 self.view_key,
157 "Address".cyan().bold(),
158 self.address
159 )
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166 use snarkvm::prelude::MainnetV0;
167
168 type CurrentNetwork = MainnetV0;
169
170 #[test]
171 fn test_sign() {
172 let mut rng = TestRng::default();
174 let account = Account::<CurrentNetwork>::new(&mut rng).unwrap();
176 let message = vec![Field::rand(&mut rng); 10];
177 let signature = account.sign(&message, &mut rng).unwrap();
179 assert!(account.verify(&message, &signature));
180 }
181
182 #[test]
183 fn test_sign_bytes() {
184 let mut rng = TestRng::default();
186 let account = Account::<CurrentNetwork>::new(&mut rng).unwrap();
188
189 let message = (0..10).map(|_| rng.r#gen::<u8>()).collect::<Vec<u8>>();
191 let signature = account.sign_bytes(&message, &mut rng).unwrap();
193 assert!(account.verify_bytes(&message, &signature));
194 }
195
196 #[test]
197 fn test_sign_bits() {
198 let mut rng = TestRng::default();
200 let account = Account::<CurrentNetwork>::new(&mut rng).unwrap();
202 let message = (0..10).map(|_| rng.r#gen::<bool>()).collect::<Vec<bool>>();
203 let signature = account.sign_bits(&message, &mut rng).unwrap();
205 assert!(account.verify_bits(&message, &signature));
206 }
207}