use crate::{
DIDWebVHError, DIDWebVHState,
log_entry::LogEntryMethods,
resolve::{DIDWebVH, ResolveOptions},
};
use ssi::dids::{
DIDMethod, DIDMethodResolver, Document,
document::{
self,
representation::{self, MediaType},
},
resolution::{self, Error, Options},
};
use tracing::{Instrument, Level, span};
impl DIDMethodResolver for DIDWebVH {
async fn resolve_method_representation<'a>(
&'a self,
method_specific_id: &'a str,
options: Options,
) -> Result<ssi::dids::resolution::Output<Vec<u8>>, Error> {
let _span = span!(
Level::DEBUG,
"DIDWebVH::resolve_method_representation",
method_specific_id = method_specific_id
);
async move {
let mut state = DIDWebVHState::default();
match state
.resolve(method_specific_id, ResolveOptions::default())
.await
{
Ok((log_entry, _)) => {
let document: Document = serde_json::from_value(log_entry.get_state().clone())
.map_err(|e| {
Error::internal(format!("Failed to parse DID Document: {e}"))
})?;
let content_type = options.accept.unwrap_or(MediaType::Json);
let represented = document.into_representation(representation::Options::Json);
Ok(resolution::Output::new(
represented.to_bytes(),
document::Metadata::default(),
resolution::Metadata::from_content_type(Some(content_type.to_string())),
))
}
Err(DIDWebVHError::NotFound(_)) => Err(Error::NotFound),
Err(e) => Err(Error::Internal(e.to_string())),
}
}
.instrument(_span)
.await
}
}
impl DIDMethod for DIDWebVH {
const DID_METHOD_NAME: &'static str = "webvh";
}
#[cfg(test)]
mod tests {
use ssi::dids::{DID, DIDResolver};
use crate::resolve::DIDWebVH;
#[tokio::test]
#[ignore] async fn resolve_reference() {
let webvh = DIDWebVH;
unsafe {
let result = webvh.resolve(
DID::new_unchecked("did:webvh:Qmd1FCL9Vj2vJ433UDfC9MBstK6W6QWSQvYyeNn8va2fai:identity.foundation:didwebvh-implementations:implementations:affinidi-didwebvh-rs".as_bytes()),
).await;
assert!(result.is_ok());
}
}
#[tokio::test]
#[ignore] async fn resolve_reference_specific_version() {
let webvh = DIDWebVH;
unsafe {
let result = webvh.resolve(DID::new_unchecked(
"did:webvh:Qmd1FCL9Vj2vJ433UDfC9MBstK6W6QWSQvYyeNn8va2fai:identity.foundation:didwebvh-implementations:implementations:affinidi-didwebvh-rs?versionId=2-QmUCFFYYGBJhzZqyouAtvRJ7ULdd8FqSUvwb61FPTMH1Aj".as_bytes()),
).await;
assert!(result.is_ok());
}
}
#[tokio::test]
#[ignore] async fn resolve_reference_specific_time() {
let webvh = DIDWebVH;
unsafe {
let result = webvh.resolve(DID::new_unchecked(
"did:webvh:Qmd1FCL9Vj2vJ433UDfC9MBstK6W6QWSQvYyeNn8va2fai:identity.foundation:didwebvh-implementations:implementations:affinidi-didwebvh-rs?versionTime=2025-08-01T00:00:00Z".as_bytes()),
).await;
assert!(result.is_ok());
}
}
}