use zeroize::Zeroize;
use sp_core::{crypto::*, ed25519, sr25519};
use sp_keystore::*;
pub struct Keystore(sr25519::Pair);
impl Keystore {
pub fn from_env() -> Option<Self> {
let mut key_hex = serai_env::var("KEY")?;
if key_hex.trim().is_empty() {
None?;
}
let mut key = hex::decode(&key_hex).expect("KEY from environment wasn't hex");
key_hex.zeroize();
assert_eq!(key.len(), 32, "KEY from environment wasn't 32 bytes");
key.extend(sp_core::blake2_256(&key));
let res = Self(sr25519::Pair::from(schnorrkel::SecretKey::from_bytes(&key).unwrap()));
key.zeroize();
Some(res)
}
}
impl sp_keystore::Keystore for Keystore {
fn sr25519_public_keys(&self, _: KeyTypeId) -> Vec<sr25519::Public> {
vec![self.0.public()]
}
fn sr25519_generate_new(&self, _: KeyTypeId, _: Option<&str>) -> Result<sr25519::Public, Error> {
panic!("asked to generate an sr25519 key");
}
fn sr25519_sign(
&self,
_: KeyTypeId,
public: &sr25519::Public,
msg: &[u8],
) -> Result<Option<sr25519::Signature>, Error> {
if public == &self.0.public() {
Ok(Some(self.0.sign(msg)))
} else {
Ok(None)
}
}
fn sr25519_vrf_sign(
&self,
_: KeyTypeId,
public: &sr25519::Public,
data: &sr25519::vrf::VrfSignData,
) -> Result<Option<sr25519::vrf::VrfSignature>, Error> {
if public == &self.0.public() {
Ok(Some(self.0.vrf_sign(data)))
} else {
Ok(None)
}
}
fn sr25519_vrf_output(
&self,
_: KeyTypeId,
public: &sr25519::Public,
input: &sr25519::vrf::VrfInput,
) -> Result<Option<sr25519::vrf::VrfOutput>, Error> {
if public == &self.0.public() {
Ok(Some(self.0.vrf_output(input)))
} else {
Ok(None)
}
}
fn ed25519_public_keys(&self, _: KeyTypeId) -> Vec<ed25519::Public> {
panic!("asked for ed25519 keys");
}
fn ed25519_generate_new(&self, _: KeyTypeId, _: Option<&str>) -> Result<ed25519::Public, Error> {
panic!("asked to generate an ed25519 key");
}
fn ed25519_sign(
&self,
_: KeyTypeId,
_: &ed25519::Public,
_: &[u8],
) -> Result<Option<ed25519::Signature>, Error> {
panic!("asked to produce an ed25519 signature");
}
fn insert(&self, _: KeyTypeId, _: &str, _: &[u8]) -> Result<(), ()> {
panic!("asked to insert a key");
}
fn keys(&self, _: KeyTypeId) -> Result<Vec<Vec<u8>>, Error> {
Ok(vec![self.0.public().0.to_vec()])
}
fn has_keys(&self, public_keys: &[(Vec<u8>, KeyTypeId)]) -> bool {
let our_key = self.0.public().0;
for (public_key, _) in public_keys {
if our_key != public_key.as_slice() {
return false;
}
}
true
}
}