use anyhow::Result; use ed25519_dalek::Signer; use ed25519_dalek::SigningKey; use tonic::metadata::AsciiMetadataValue; use tonic::Request; pub const WALLET_KEY_PATH: &str = "tests/fixtures/secret_detee_wallet_key"; pub fn sign_request(req: T) -> Result> { let pubkey = get_pub_key()?; let timestamp = chrono::Utc::now().to_rfc3339(); let signature = 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) } fn get_signing_key() -> Result { let key = bs58::decode(std::fs::read_to_string(WALLET_KEY_PATH)?.trim()) .into_vec()? .try_into() .map_err(|e: Vec| anyhow::anyhow!("Invalid key length: {}", e.len()))?; let key = SigningKey::from_bytes(&key); Ok(key) } pub fn get_pub_key() -> Result { let key = get_signing_key()?; Ok(bs58::encode(key.verifying_key().to_bytes()).into_string()) } pub fn try_sign_message(message: &str) -> Result { let key = get_signing_key()?; Ok(bs58::encode(key.sign(message.as_bytes()).to_bytes()).into_string()) }