use affinidi_messaging_didcomm_service::{
DIDCommServiceError, HandlerContext, TspHandler, TspResponse,
};
use async_trait::async_trait;
use serde_json::Value;
use tracing::warn;
use did_hosting_common::server::tsp_binding;
use crate::server::AppState;
use crate::trust_tasks::{Via, dispatch_inbound_document};
pub struct WatcherTspHandler {
state: AppState,
}
impl WatcherTspHandler {
pub fn new(state: AppState) -> Self {
Self { state }
}
}
pub async fn run_tsp_trust_task(
state: &AppState,
sender_vid: &str,
payload: &[u8],
) -> Result<Option<Vec<u8>>, DIDCommServiceError> {
let (document, carriage) = tsp_binding::open(payload);
let doc = match serde_json::from_slice::<trust_tasks_rs::TrustTask<Value>>(&document) {
Ok(doc) => doc,
Err(e) => {
warn!(
sender = %sender_vid,
error = %e,
"inbound TSP: payload is not a Trust Task document — dropped"
);
return Ok(None);
}
};
match dispatch_inbound_document(state, Via::Tsp, Some(sender_vid), doc).await {
Some(reply) => Ok(Some(tsp_binding::frame(
serde_json::to_vec(&reply).map_err(|e| DIDCommServiceError::Internal(e.to_string()))?,
carriage,
))),
None => Ok(None),
}
}
#[async_trait]
impl TspHandler for WatcherTspHandler {
async fn handle(
&self,
_ctx: HandlerContext,
payload: Vec<u8>,
sender_vid: String,
) -> Result<Option<TspResponse>, DIDCommServiceError> {
match run_tsp_trust_task(&self.state, &sender_vid, &payload).await? {
Some(frame) => Ok(Some(TspResponse::new(frame))),
None => Ok(None),
}
}
async fn handle_control(
&self,
ctx: HandlerContext,
control: affinidi_tsp::message::control::ControlMessage,
sender_vid: String,
thread_digest: [u8; 32],
) {
did_hosting_common::server::tsp_relationship::answer_inbound_control(
&ctx,
&control,
&sender_vid,
thread_digest,
)
.await
}
}