39 lines
1.3 KiB
Rust
39 lines
1.3 KiB
Rust
use anyhow::Result;
|
|
use ed25519_dalek::Signer;
|
|
use ed25519_dalek::SigningKey;
|
|
use tonic::metadata::AsciiMetadataValue;
|
|
use tonic::Request;
|
|
|
|
pub struct Key {
|
|
pub sg_key: SigningKey,
|
|
pub pubkey: String,
|
|
}
|
|
|
|
impl Key {
|
|
pub fn new() -> Self {
|
|
let sk = SigningKey::generate(&mut rand::rngs::OsRng);
|
|
let pubkey = bs58::encode(sk.verifying_key().to_bytes()).into_string();
|
|
Key { sg_key: sk, pubkey }
|
|
}
|
|
|
|
pub fn sign_request<T: std::fmt::Debug>(&self, req: T) -> Result<Request<T>> {
|
|
let pubkey = self.pubkey.clone();
|
|
let timestamp = chrono::Utc::now().to_rfc3339();
|
|
let signature = self.try_sign_message(&format!("{timestamp}{req:?}"))?;
|
|
let timestamp: AsciiMetadataValue = timestamp.parse()?;
|
|
let pubkey: AsciiMetadataValue = pubkey.parse()?;
|
|
let signature: AsciiMetadataValue = signature.parse()?;
|
|
let mut req = Request::new(req);
|
|
req.metadata_mut().insert("timestamp", timestamp);
|
|
req.metadata_mut().insert("pubkey", pubkey);
|
|
req.metadata_mut().insert("request-signature", signature);
|
|
|
|
Ok(req)
|
|
}
|
|
|
|
pub fn try_sign_message(&self, message: &str) -> Result<String> {
|
|
let key = self.sg_key.clone();
|
|
Ok(bs58::encode(key.sign(message.as_bytes()).to_bytes()).into_string())
|
|
}
|
|
}
|