Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vcdm 2.0 model and context #3436

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add vcdm 2.0 model and context
Signed-off-by: PatStLouis <[email protected]>
PatStLouis committed Jan 10, 2025
commit 7ba9b99677f00be60ab3b2ed91781c917b9f0167
11 changes: 7 additions & 4 deletions acapy_agent/messaging/valid.py
Original file line number Diff line number Diff line change
@@ -875,8 +875,11 @@ def __call__(self, value):
class CredentialContext(Validator):
"""Credential Context."""

FIRST_CONTEXT = "https://www.w3.org/2018/credentials/v1"
EXAMPLE = [FIRST_CONTEXT, "https://www.w3.org/2018/credentials/examples/v1"]
FIRST_CONTEXT = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps rename to a VALID_CONTEXTS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I agree

"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/ns/credentials/v2",
]
EXAMPLE = [FIRST_CONTEXT[0], "https://www.w3.org/2018/credentials/examples/v1"]

def __init__(self) -> None:
"""Initialize the instance."""
@@ -886,9 +889,9 @@ def __call__(self, value):
"""Validate input value."""
length = len(value)

if length < 1 or value[0] != CredentialContext.FIRST_CONTEXT:
if length < 1 or value[0] not in CredentialContext.FIRST_CONTEXT:
raise ValidationError(
f"First context must be {CredentialContext.FIRST_CONTEXT}"
f"First context must be one of {CredentialContext.FIRST_CONTEXT}"
)

return value
Comment on lines 898 to 906
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If value is None, there would be a TypeError.

Probably worth asserting that value is of expected type before calling len or [0].
(because a dev could try call with a string, and get unclear error message).

Something like:

    def __call__(self, value: List[str]) -> List[str]:
        """Validate input value."""
        if not isinstance(value, list):
            raise ValidationError("Value must be a non-empty list.")

        if not value or value[0] not in CredentialContext.FIRST_CONTEXT:
            raise ValidationError(
                f"First context must be one of {CredentialContext.FIRST_CONTEXT}"
            )

        return value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can implement this, however this type of validation would of been done at the datamodel version in the class invoking this validation

1 change: 1 addition & 0 deletions acapy_agent/vc/ld_proofs/constants.py
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
SECURITY_CONTEXT_URL = SECURITY_CONTEXT_V2_URL
DID_V1_CONTEXT_URL = "https://www.w3.org/ns/did/v1"
CREDENTIALS_CONTEXT_V1_URL = "https://www.w3.org/2018/credentials/v1"
CREDENTIALS_CONTEXT_V2_URL = "https://www.w3.org/ns/credentials/v2"
SECURITY_CONTEXT_BBS_URL = "https://w3id.org/security/bbs/v1"
SECURITY_CONTEXT_ED25519_2020_URL = "https://w3id.org/security/suites/ed25519-2020/v1"

1 change: 1 addition & 0 deletions acapy_agent/vc/ld_proofs/document_downloader.py
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ class StaticCacheJsonLdDownloader:

CONTEXT_FILE_MAPPING = {
"https://www.w3.org/2018/credentials/v1": "credentials_context.jsonld",
"https://www.w3.org/ns/credentials/v2": "credentials_v2_context.jsonld",
"https://w3id.org/vc/status-list/2021/v1": "status_list_context.jsonld",
"https://www.w3.org/ns/did/v1": "did_documents_context.jsonld",
"https://w3id.org/security/v1": "security-v1-context.jsonld",
301 changes: 301 additions & 0 deletions acapy_agent/vc/ld_proofs/resources/credentials_v2_context.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
{
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"description": "https://schema.org/description",
"digestMultibase": {
"@id": "https://w3id.org/security#digestMultibase",
"@type": "https://w3id.org/security#multibase"
},
"digestSRI": {
"@id": "https://www.w3.org/2018/credentials#digestSRI",
"@type": "https://www.w3.org/2018/credentials#sriString"
},
"mediaType": {
"@id": "https://schema.org/encodingFormat"
},
"name": "https://schema.org/name",
"VerifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#VerifiableCredential",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"confidenceMethod": {
"@id": "https://www.w3.org/2018/credentials#confidenceMethod",
"@type": "@id"
},
"credentialSchema": {
"@id": "https://www.w3.org/2018/credentials#credentialSchema",
"@type": "@id"
},
"credentialStatus": {
"@id": "https://www.w3.org/2018/credentials#credentialStatus",
"@type": "@id"
},
"credentialSubject": {
"@id": "https://www.w3.org/2018/credentials#credentialSubject",
"@type": "@id"
},
"description": "https://schema.org/description",
"evidence": {
"@id": "https://www.w3.org/2018/credentials#evidence",
"@type": "@id"
},
"issuer": {
"@id": "https://www.w3.org/2018/credentials#issuer",
"@type": "@id"
},
"name": "https://schema.org/name",
"proof": {
"@id": "https://w3id.org/security#proof",
"@type": "@id",
"@container": "@graph"
},
"refreshService": {
"@id": "https://www.w3.org/2018/credentials#refreshService",
"@type": "@id"
},
"relatedResource": {
"@id": "https://www.w3.org/2018/credentials#relatedResource",
"@type": "@id"
},
"renderMethod": {
"@id": "https://www.w3.org/2018/credentials#renderMethod",
"@type": "@id"
},
"termsOfUse": {
"@id": "https://www.w3.org/2018/credentials#termsOfUse",
"@type": "@id"
},
"validFrom": {
"@id": "https://www.w3.org/2018/credentials#validFrom",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"validUntil": {
"@id": "https://www.w3.org/2018/credentials#validUntil",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
}
}
},
"EnvelopedVerifiableCredential": "https://www.w3.org/2018/credentials#EnvelopedVerifiableCredential",
"VerifiablePresentation": {
"@id": "https://www.w3.org/2018/credentials#VerifiablePresentation",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"holder": {
"@id": "https://www.w3.org/2018/credentials#holder",
"@type": "@id"
},
"proof": {
"@id": "https://w3id.org/security#proof",
"@type": "@id",
"@container": "@graph"
},
"termsOfUse": {
"@id": "https://www.w3.org/2018/credentials#termsOfUse",
"@type": "@id"
},
"verifiableCredential": {
"@id": "https://www.w3.org/2018/credentials#verifiableCredential",
"@type": "@id",
"@container": "@graph",
"@context": null
}
}
},
"EnvelopedVerifiablePresentation": "https://www.w3.org/2018/credentials#EnvelopedVerifiablePresentation",
"JsonSchemaCredential": "https://www.w3.org/2018/credentials#JsonSchemaCredential",
"JsonSchema": {
"@id": "https://www.w3.org/2018/credentials#JsonSchema",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"jsonSchema": {
"@id": "https://www.w3.org/2018/credentials#jsonSchema",
"@type": "@json"
}
}
},
"BitstringStatusListCredential": "https://www.w3.org/ns/credentials/status#BitstringStatusListCredential",
"BitstringStatusList": {
"@id": "https://www.w3.org/ns/credentials/status#BitstringStatusList",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"encodedList": {
"@id": "https://www.w3.org/ns/credentials/status#encodedList",
"@type": "https://w3id.org/security#multibase"
},
"statusMessage": {
"@id": "https://www.w3.org/ns/credentials/status#statusMessage",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"message": "https://www.w3.org/ns/credentials/status#message",
"status": "https://www.w3.org/ns/credentials/status#status"
}
},
"statusPurpose": "https://www.w3.org/ns/credentials/status#statusPurpose",
"statusReference": {
"@id": "https://www.w3.org/ns/credentials/status#statusReference",
"@type": "@id"
},
"statusSize": {
"@id": "https://www.w3.org/ns/credentials/status#statusSize",
"@type": "https://www.w3.org/2001/XMLSchema#positiveInteger"
},
"ttl": "https://www.w3.org/ns/credentials/status#ttl"
}
},
"BitstringStatusListEntry": {
"@id": "https://www.w3.org/ns/credentials/status#BitstringStatusListEntry",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"statusListCredential": {
"@id": "https://www.w3.org/ns/credentials/status#statusListCredential",
"@type": "@id"
},
"statusListIndex": "https://www.w3.org/ns/credentials/status#statusListIndex",
"statusPurpose": "https://www.w3.org/ns/credentials/status#statusPurpose"
}
},
"DataIntegrityProof": {
"@id": "https://w3id.org/security#DataIntegrityProof",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"challenge": "https://w3id.org/security#challenge",
"created": {
"@id": "http://purl.org/dc/terms/created",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"cryptosuite": {
"@id": "https://w3id.org/security#cryptosuite",
"@type": "https://w3id.org/security#cryptosuiteString"
},
"domain": "https://w3id.org/security#domain",
"expires": {
"@id": "https://w3id.org/security#expiration",
"@type": "http://www.w3.org/2001/XMLSchema#dateTime"
},
"nonce": "https://w3id.org/security#nonce",
"previousProof": {
"@id": "https://w3id.org/security#previousProof",
"@type": "@id"
},
"proofPurpose": {
"@id": "https://w3id.org/security#proofPurpose",
"@type": "@vocab",
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"assertionMethod": {
"@id": "https://w3id.org/security#assertionMethod",
"@type": "@id",
"@container": "@set"
},
"authentication": {
"@id": "https://w3id.org/security#authenticationMethod",
"@type": "@id",
"@container": "@set"
},
"capabilityDelegation": {
"@id": "https://w3id.org/security#capabilityDelegationMethod",
"@type": "@id",
"@container": "@set"
},
"capabilityInvocation": {
"@id": "https://w3id.org/security#capabilityInvocationMethod",
"@type": "@id",
"@container": "@set"
},
"keyAgreement": {
"@id": "https://w3id.org/security#keyAgreementMethod",
"@type": "@id",
"@container": "@set"
}
}
},
"proofValue": {
"@id": "https://w3id.org/security#proofValue",
"@type": "https://w3id.org/security#multibase"
},
"verificationMethod": {
"@id": "https://w3id.org/security#verificationMethod",
"@type": "@id"
}
}
},
"...": {
"@id": "https://www.iana.org/assignments/jwt#..."
},
"_sd": {
"@id": "https://www.iana.org/assignments/jwt#_sd",
"@type": "@json"
},
"_sd_alg": {
"@id": "https://www.iana.org/assignments/jwt#_sd_alg"
},
"aud": {
"@id": "https://www.iana.org/assignments/jwt#aud",
"@type": "@id"
},
"cnf": {
"@id": "https://www.iana.org/assignments/jwt#cnf",
"@context": {
"@protected": true,
"kid": {
"@id": "https://www.iana.org/assignments/jwt#kid",
"@type": "@id"
},
"jwk": {
"@id": "https://www.iana.org/assignments/jwt#jwk",
"@type": "@json"
}
}
},
"exp": {
"@id": "https://www.iana.org/assignments/jwt#exp",
"@type": "https://www.w3.org/2001/XMLSchema#nonNegativeInteger"
},
"iat": {
"@id": "https://www.iana.org/assignments/jwt#iat",
"@type": "https://www.w3.org/2001/XMLSchema#nonNegativeInteger"
},
"iss": {
"@id": "https://www.iana.org/assignments/jose#iss",
"@type": "@id"
},
"jku": {
"@id": "https://www.iana.org/assignments/jose#jku",
"@type": "@id"
},
"kid": {
"@id": "https://www.iana.org/assignments/jose#kid",
"@type": "@id"
},
"nbf": {
"@id": "https://www.iana.org/assignments/jwt#nbf",
"@type": "https://www.w3.org/2001/XMLSchema#nonNegativeInteger"
},
"sub": {
"@id": "https://www.iana.org/assignments/jose#sub",
"@type": "@id"
},
"x5u": {
"@id": "https://www.iana.org/assignments/jose#x5u",
"@type": "@id"
}
}
}
Loading