I'm trying to see if I can get SpruceKit to accept a credential issued by Walt.ID. After patching #34, I can get to the point that it's trying to get the issuer metadata. At that point it fails with the error below:
SpruceIDMobileSdkRs.Oid4vciError.Client(message: "unable to decode JSON body from http://localhost:7002/draft13: data did not match any variant of untagged enum StandardCredentialFormatMetadata at line 1 column 1866")
You can see the metadata json at this gist. After digging a bit more, I figured out that there are some credential configurations with a format not supported by this crate, at which point it just rejects the whole thing. That seems pretty brittle. If an issuer adds a new format and you have an old client it's just going to stop accepting that issuer.
I made a unit test with this metadata and asked Gemini to just ignore any configurations that aren't supported yet. Here's the patch it produced. Honestly no idea if this is the right way to do it, but it passed my little unit test and got me to the next error in my quest.
diff --git a/src/issuer/metadata.rs b/src/issuer/metadata.rs
index e7e9e7d..75da37e 100644
--- a/src/issuer/metadata.rs
+++ b/src/issuer/metadata.rs
@@ -105,6 +105,7 @@ where
///
/// List of name/value pairs, where each name is a unique identifier of the
/// supported Credential being described.
+ #[serde(deserialize_with = "deserialize_credential_configurations_supported")]
pub credential_configurations_supported: IndexMap<String, CredentialConfiguration<F>>,
}
@@ -532,9 +533,47 @@ pub struct CredentialConfigurationsSupported<
F: CredentialFormatMetadata = StandardCredentialFormatMetadata,
> {
#[allow(unused)]
+ #[serde(deserialize_with = "deserialize_credential_configurations_supported")]
pub credential_configurations_supported: IndexMap<String, CredentialConfiguration<F>>,
}
+fn deserialize_credential_configurations_supported<'de, D, F>(
+ deserializer: D,
+) -> Result<IndexMap<String, CredentialConfiguration<F>>, D::Error>
+where
+ D: serde::Deserializer<'de>,
+ F: CredentialFormatMetadata,
+{
+ use serde::de::{MapAccess, Visitor};
+ use std::fmt;
+
+ struct MapVisitor<F>(std::marker::PhantomData<F>);
+
+ impl<'de, F: CredentialFormatMetadata> Visitor<'de> for MapVisitor<F> {
+ type Value = IndexMap<String, CredentialConfiguration<F>>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a map of credential configurations")
+ }
+
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut result = IndexMap::new();
+ while let Some(key) = map.next_key::<String>()? {
+ let value: serde_json::Value = map.next_value()?;
+ if let Ok(config) = serde_json::from_value(value) {
+ result.insert(key, config);
+ }
+ }
+ Ok(result)
+ }
+ }
+
+ deserializer.deserialize_map(MapVisitor(std::marker::PhantomData))
+}
+
#[cfg(feature = "axum")]
mod axum {
use ::axum::{
@@ -584,6 +623,15 @@ mod test {
serde_json::from_str(include_str!("../tests/issuer/metadata/example.json")).unwrap();
}
+ #[test]
+ fn walt_id() {
+ let metadata: CredentialIssuerMetadata =
+ serde_json::from_str(include_str!("../tests/issuer/metadata/walt.id.json")).unwrap();
+ assert!(metadata
+ .credential_configurations_supported
+ .contains_key("org.iso.18013.5.1.mDL"));
+ }
+
#[test]
fn example_additional() {
let _: CredentialIssuerMetadata = serde_json::from_str(include_str!(
I'm trying to see if I can get SpruceKit to accept a credential issued by Walt.ID. After patching #34, I can get to the point that it's trying to get the issuer metadata. At that point it fails with the error below:
SpruceIDMobileSdkRs.Oid4vciError.Client(message: "unable to decode JSON body from http://localhost:7002/draft13: data did not match any variant of untagged enum StandardCredentialFormatMetadata at line 1 column 1866")
You can see the metadata json at this gist. After digging a bit more, I figured out that there are some credential configurations with a format not supported by this crate, at which point it just rejects the whole thing. That seems pretty brittle. If an issuer adds a new format and you have an old client it's just going to stop accepting that issuer.
I made a unit test with this metadata and asked Gemini to just ignore any configurations that aren't supported yet. Here's the patch it produced. Honestly no idea if this is the right way to do it, but it passed my little unit test and got me to the next error in my quest.