1use core::fmt;
2use core::ops::{Deref, DerefMut};
3use core::str::FromStr;
4#[cfg(not(target_arch = "wasm32"))]
5use std::{io, path::Path};
6
7use serde::{Deserialize, Serialize};
8
9type ParseError = <pkarr::PublicKey as TryFrom<String>>::Error;
10
11fn parse_public_key(value: &str) -> Result<pkarr::PublicKey, ParseError> {
12 let raw = if PublicKey::is_pubky_prefixed(value) {
13 value.strip_prefix("pubky").unwrap_or(value)
14 } else {
15 value
16 };
17 pkarr::PublicKey::try_from(raw.to_string())
18}
19
20#[derive(Clone)]
22pub struct Keypair(pkarr::Keypair);
23
24impl Keypair {
25 #[must_use]
27 pub fn random() -> Self {
28 Self(pkarr::Keypair::random())
29 }
30
31 #[must_use]
33 pub fn secret(&self) -> [u8; 32] {
34 let mut out = [0u8; 32];
35 out.copy_from_slice(self.0.secret_key().as_ref());
36 out
37 }
38
39 #[must_use]
41 pub fn from_secret(secret: &[u8; 32]) -> Self {
42 Self(pkarr::Keypair::from_secret_key(secret))
43 }
44
45 #[cfg(not(target_arch = "wasm32"))]
47 pub fn from_secret_key_file(path: &Path) -> Result<Self, io::Error> {
48 pkarr::Keypair::from_secret_key_file(path).map(Self)
49 }
50
51 #[must_use]
56 pub fn public_key(&self) -> PublicKey {
57 PublicKey(self.0.public_key())
58 }
59
60 #[must_use]
62 pub const fn as_inner(&self) -> &pkarr::Keypair {
63 &self.0
64 }
65
66 #[cfg(not(target_arch = "wasm32"))]
68 pub fn write_secret_key_file(&self, path: &Path) -> Result<(), io::Error> {
69 self.0.write_secret_key_file(path)
70 }
71
72 #[must_use]
74 pub fn into_inner(self) -> pkarr::Keypair {
75 self.0
76 }
77}
78
79impl fmt::Debug for Keypair {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 self.0.fmt(f)
82 }
83}
84
85impl Deref for Keypair {
86 type Target = pkarr::Keypair;
87
88 fn deref(&self) -> &Self::Target {
89 &self.0
90 }
91}
92
93impl DerefMut for Keypair {
94 fn deref_mut(&mut self) -> &mut Self::Target {
95 &mut self.0
96 }
97}
98
99impl From<pkarr::Keypair> for Keypair {
100 fn from(keypair: pkarr::Keypair) -> Self {
101 Self(keypair)
102 }
103}
104
105impl From<Keypair> for pkarr::Keypair {
106 fn from(value: Keypair) -> Self {
107 value.0
108 }
109}
110
111#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
116#[serde(transparent)]
117pub struct PublicKey(pkarr::PublicKey);
118
119impl PublicKey {
120 pub fn is_pubky_prefixed(value: &str) -> bool {
122 matches!(value.strip_prefix("pubky"), Some(stripped) if stripped.len() == 52)
123 }
124
125 #[must_use]
127 pub const fn as_inner(&self) -> &pkarr::PublicKey {
128 &self.0
129 }
130
131 #[must_use]
133 pub fn into_inner(self) -> pkarr::PublicKey {
134 self.0
135 }
136
137 #[must_use]
142 pub fn z32(&self) -> String {
143 self.0.to_string()
144 }
145
146 pub fn try_from_z32(value: &str) -> Result<Self, ParseError> {
148 pkarr::PublicKey::try_from(value.to_string()).map(Self)
149 }
150}
151
152impl fmt::Display for PublicKey {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 write!(f, "pubky{}", self.z32())
155 }
156}
157
158impl fmt::Debug for PublicKey {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 f.debug_tuple("PublicKey").field(&self.to_string()).finish()
161 }
162}
163
164impl Deref for PublicKey {
165 type Target = pkarr::PublicKey;
166
167 fn deref(&self) -> &Self::Target {
168 &self.0
169 }
170}
171
172impl From<pkarr::PublicKey> for PublicKey {
173 fn from(value: pkarr::PublicKey) -> Self {
174 Self(value)
175 }
176}
177
178impl From<&pkarr::PublicKey> for PublicKey {
179 fn from(value: &pkarr::PublicKey) -> Self {
180 Self(value.clone())
181 }
182}
183
184impl From<PublicKey> for pkarr::PublicKey {
185 fn from(value: PublicKey) -> Self {
186 value.0
187 }
188}
189
190impl From<&PublicKey> for pkarr::PublicKey {
191 fn from(value: &PublicKey) -> Self {
192 value.0.clone()
193 }
194}
195
196impl TryFrom<&str> for PublicKey {
197 type Error = ParseError;
198
199 fn try_from(value: &str) -> Result<Self, Self::Error> {
200 parse_public_key(value).map(Self)
201 }
202}
203
204impl TryFrom<&String> for PublicKey {
205 type Error = ParseError;
206
207 fn try_from(value: &String) -> Result<Self, Self::Error> {
208 parse_public_key(value).map(Self)
209 }
210}
211
212impl TryFrom<String> for PublicKey {
213 type Error = ParseError;
214
215 fn try_from(value: String) -> Result<Self, Self::Error> {
216 parse_public_key(&value).map(Self)
217 }
218}
219
220impl FromStr for PublicKey {
221 type Err = ParseError;
222
223 fn from_str(s: &str) -> Result<Self, Self::Err> {
224 parse_public_key(s).map(Self)
225 }
226}