use affinidi_tdk::secrets_resolver::secrets::Secret;
use serde_json::Value;
use trust_tasks_proof::affinidi::{CryptoSuite, SignOptions, sign_trust_task};
use crate::error::AppError;
use crate::server::AppState;
pub fn control_assertion_secret(state: &AppState, control_did: &str) -> Result<Secret, AppError> {
let identity = state.identity.as_deref().ok_or_else(|| {
AppError::Internal(
"service identity not loaded; cannot sign the outbound request document".into(),
)
})?;
let generation = identity.current();
if generation.did != control_did {
return Err(AppError::Internal(format!(
"current identity generation DID {} does not match the configured server_did {control_did}",
generation.did
)));
}
identity
.secrets()
.into_iter()
.find(|s| s.id == generation.signing_kid)
.ok_or_else(|| {
AppError::Internal(format!(
"no signing secret loaded for {}; cannot sign the outbound request document",
generation.signing_kid
))
})
}
pub async fn sign_trust_task_document(
unsigned: Value,
signing_secret: &Secret,
) -> Result<Value, AppError> {
debug_assert!(
unsigned.get("proof").is_none(),
"document to sign must not already carry a proof"
);
sign_trust_task(
&unsigned,
signing_secret,
SignOptions::new()
.with_proof_purpose("assertionMethod")
.with_cryptosuite(CryptoSuite::EddsaJcs2022),
)
.await
.map_err(|e| AppError::Internal(format!("sign trust task document: {e}")))
}
#[cfg(test)]
pub(crate) mod test_util {
use super::*;
pub(crate) fn did_key_signer(seed: &[u8; 32]) -> (String, Secret) {
let secret = Secret::generate_ed25519(None, Some(seed));
let pk_mb = secret.get_public_keymultibase().expect("multibase pubkey");
let did = format!("did:key:{pk_mb}");
let mut signer = secret;
signer.id = format!("{did}#{pk_mb}");
(did, signer)
}
}