penumbra_sdk_stake/
identity_key.rs1use penumbra_sdk_proto::{
2 core::component::stake::v1::CurrentValidatorRateRequest,
3 core::keys::v1 as pb,
5 serializers::bech32str::{self, validator_identity_key::BECH32_PREFIX},
6 DomainType,
7};
8use serde::{Deserialize, Serialize};
9
10use decaf377_rdsa::{SpendAuth, VerificationKeyBytes};
11
12pub const IDENTITY_KEY_LEN_BYTES: usize = 32;
15
16#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
26#[serde(try_from = "pb::IdentityKey", into = "pb::IdentityKey")]
27pub struct IdentityKey(pub VerificationKeyBytes<SpendAuth>);
28
29impl IdentityKey {
30 pub fn to_bytes(&self) -> [u8; IDENTITY_KEY_LEN_BYTES] {
31 self.0.into()
32 }
33}
34
35impl std::str::FromStr for IdentityKey {
37 type Err = anyhow::Error;
38 fn from_str(s: &str) -> Result<Self, Self::Err> {
39 pb::IdentityKey {
40 ik: bech32str::decode(s, BECH32_PREFIX, bech32str::Bech32m)?,
41 }
42 .try_into()
43 }
44}
45
46impl std::fmt::Display for IdentityKey {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 f.write_str(&bech32str::encode(
50 self.0.as_ref(),
51 BECH32_PREFIX,
52 bech32str::Bech32m,
53 ))
54 }
55}
56
57impl std::fmt::Debug for IdentityKey {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 <IdentityKey as std::fmt::Display>::fmt(self, f)
60 }
61}
62
63impl DomainType for IdentityKey {
64 type Proto = pb::IdentityKey;
65}
66
67impl From<IdentityKey> for pb::IdentityKey {
68 fn from(ik: IdentityKey) -> Self {
69 pb::IdentityKey {
70 ik: ik.0.as_ref().to_vec(),
71 }
72 }
73}
74
75impl TryFrom<pb::IdentityKey> for IdentityKey {
76 type Error = anyhow::Error;
77 fn try_from(ik: pb::IdentityKey) -> Result<Self, Self::Error> {
78 Ok(Self(ik.ik.as_slice().try_into()?))
79 }
80}
81
82impl From<IdentityKey> for CurrentValidatorRateRequest {
83 fn from(k: IdentityKey) -> Self {
84 CurrentValidatorRateRequest {
85 identity_key: Some(k.into()),
86 }
87 }
88}
89
90impl TryFrom<CurrentValidatorRateRequest> for IdentityKey {
91 type Error = anyhow::Error;
92 fn try_from(value: CurrentValidatorRateRequest) -> Result<Self, Self::Error> {
93 value
94 .identity_key
95 .ok_or_else(|| anyhow::anyhow!("empty CurrentValidatorRateRequest message"))?
96 .try_into()
97 }
98}