Overview
The walt.id verifiable credentials lib offers the use of data functions when creating and issuing W3C Verifiable Credentials.
These functions offer a way to update data present in the credential data structure after it has been build using
the CredentialBuilder
and before it is signed as JWT or SD-JWT. This is probably not required for most use-cases,
however, can be extremely helpful when,
for example, building an API. As it is the case with the walt.id issuer API.
Below you find an example of how you can use data functions.
Using Data Functions
First we create a credential using the CredentialBuilder
and then we apply the data functions and sign the resulting
Verifiable Credential as JWT. A full list of available Data functions can be
found here.
import id.walt.credentials.CredentialBuilder
import id.walt.credentials.CredentialBuilderType
import id.walt.crypto.keys.KeyType
import id.walt.crypto.keys.LocalKey
import id.walt.crypto.utils.JsonUtils.toJsonObject
import id.walt.did.dids.DidService
import kotlinx.serialization.json.JsonPrimitive
import kotlin.time.Duration.Companion.days
suspend fun main() {
DidService.minimalInit() // initialising the local DID registry and resolver
val myIssuerKey = LocalKey.generate(KeyType.Ed25519)
val myIssuerDid = DidService.registerByKey("key", myIssuerKey).did
val mySubjectKey = LocalKey.generate(KeyType.Ed25519)
val mySubjectDid = DidService.registerByKey("key", mySubjectKey).did
// Defining the credential
val credentialBuilder = CredentialBuilder(CredentialBuilderType.W3CV11Creden tialBuilder).apply {
// Adds context next to default "https://www.w3.org/2018/credentials/v1"
addContext("https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json")
// Adds type next to default "VerifiableCredential"
addType("OpenBadgeCredential")
credentialId = "urn:uuid:4177e048-9a4a-474e-9dc6-aed4e61a6439"
issuerDid = myIssuerDid
// Sets issuance date to current time - 1.5 min
validFromNow()
// Adds expiration date
validFor(2.days)
subjectDid = mySubjectDid
// Used to add any custom data
useData("name", JsonPrimitive("JFF x vc-edu PlugFest 3 Interoperability"))
useData("test", JsonPrimitive(""))
// Used to insert credential subject data
useCredentialSubject(
mapOf(
"type" to listOf("AchievementSubject"),
"achievement" to mapOf(
"id" to "urn:uuid:ac254bd5-8fad-4bb1-9d29-efd938536926",
"type" to listOf("Achievement"),
"name" to "JFF x vc-edu PlugFest 3 Interoperability",
"description" to "This wallet supports the use of W3C Verifiable Credentials and has demonstrated interoperability during the presentation request workflow during JFF x VC-EDU PlugFest 3.",
"criteria" to mapOf(
"type" to "Criteria",
"narrative" to "Wallet solutions providers earned this badge by demonstrating interoperability during the presentation request workflow. This includes successfully receiving a presentation request, allowing the holder to select at least two types of verifiable credentials to create a verifiable presentation, returning the presentation to the requestor, and passing verification of the presentation and the included credentials."
),
"image" to mapOf(
"id" to "https://w3c-ccg.github.io/vc-ed/plugfest-3-2023/images/JFF-VC-EDU-PLUGFEST3-badge-image.png",
"type" to "Image"
)
)
).toJsonObject()
)
}
// building the credential
val credential = credentialBuilder.buildW3C()
// DATA FUNCTIONS PART
// using data functions to replace values in the defined credential structure above
// and signing it as JWT
val jwt = credential.mergingJwtIssue(
myIssuerKey, myIssuerDid, mySubjectDid, JsonObject(
mapOf(
"test" to JsonPrimitive("<timestamp-in:2d>") // here the value
// of test in the defined credential above
// will be replaced with the return
// value of the timestamp-in data function
)
), emptyMap(), emptyMap()
)
println(jwt)
}