Skip to content

Credential Verification

Verification Requests

Think of a verification request like asking someone for their ID.

You want to confirm a specific credential of theirs, say, their email address. You send a request to the issuer of the credential (the one who "issued their ID"). The issuer can either give a thumbs-up (approve) or thumbs-down (reject).

How to Send a Verification Request

This is akin to saying, "Hey, can you confirm this is Bob's email address? It's bob@test.com."

content, err := message.NewCredentialVerificationRequest().
    Type([]string{"VerifiableCredential", "EmailCredential"}).
    Parameter("email", "bob@test.com").
    Expires(time.Now().Add(time.Hour * 24)).
    Finish()
if err != nil {
    // handle error
}

err = selfAccount.MessageSend(address, content)
if err != nil {
    // handle error
}
1
2
3
4
5
6
7
8
val request = CredentialVerificationRequestBuilder()
    .type(arrayOf("VerifiableCredential", "EmailCredential"))
    .parameter("email", "bob@test.com")
    .expires(Timestamp.now() + 3600 * 24)
    .finish()

val sendStatus = account.messageSend(address, request)
println("send verification request status:${sendStatus.code()} - requestId:${request.id().toHexString()}")
val emailDTO = DataObject.Builder()
    .setData("bob@test.com".encodeToByteArray())
    .setContentType("text/plain")
    .build()
val codeDTO = DataObject.Builder()
    .setData("123456".encodeToByteArray()) // code from SecurityCodeRequest
    .setContentType("text/plain")
    .build()

val proofs = mapOf(
    Constants.SUBJECT_EMAIL to emailDTO,
    Constants.SUBJECT_SECURITY_CODE to codeDTO,
)

val verificationRequest = VerificationRequest.Builder()
    .setTypes(listOf(CredentialType.Email))
    .setProofs(proofs)
    .build()

account.send(verificationRequest) { messageId, error ->
    println("verification request $messageId")
}
let emailDTO = DataObject.Builder()
    .withData("bob@test.com".data(using: .utf8))
    .withContentType("text/plain")
    .build()
let codeDTO = DataObject.Builder()
    .withData("123456".data(using: .utf8))
    .withContentType("text/plain")
    .build()

let proofs = [
    Constants.SUBJECT_EMAIL: emailDTO,
    Constants.SUBJECT_SECURITY_CODE: codeDTO,
]

let verificationRequest = VerificationRequest.Builder()
        .withTypes([CredentialType.Email])
        .withProofs(proofs)
        .build()

// send the request
Task(priority: .background, operation: {
    try await self.account.send(message: verificationRequest, onAcknowledgement: {requestId, error in
        print("sent verification request: \(requestId) with error: \(error)")
    })
})

How to Receive a Verification Response

case message.TypeCredentialVerificationResponse:
    response, err := message.DecodeCredentialVerificationResponse(msg)
    if err != nil {
        // handle error
    }

    // Check the status
    log.Info("Response received with status", "status", response.Status())

    // Validate each credential
    for _, c := range response.Credentials() {
        err = c.Validate()
        if err != nil {
            // handle error
            continue
        }

        claims, err := c.CredentialSubjectClaims()
        if err != nil {
            // handle error
            continue
        }

        // Access specific claims
        println(claims["email"])
    }
ContentType.CREDENTIAL_VERIFICATION_RESPONSE -> {
    val response = CredentialVerificationResponse.decode(content)
    println("Response received with status: ${response.status().name}")

    // Validate each credential
    response.credentials().forEach { credential ->
        try {
            credential.validate()
            val claims = credential.credentialSubjectClaims()

            // Access specific claims
            println("Email: ${claims["email"]}")
        } catch (ex: Exception) {
            println("Failed to validate credential: ${ex.message}")
        }
    }
}
account.setOnResponseListener { msg ->
    when (msg) {
        is VerificationResponse -> {
            println("Response received with status:${msg.status().name}")
            msg.credentials().forEach { credential ->
                println("credential types: ${credential.types()}")
                credential.claims().forEach { claim ->
                    println("email value ${claim.value()}")
                }
            }
        }
    }
}
account.setOnResponseListener { message in
    print("setOnResponseListener: \(message)")
    switch message {
    case is VerificationResponse:
        let response = message as! VerificationResponse
        print("Handle verification response: \(response)")

    default:
        print("TODO: Handle For other response: \(message)")
        break;
    }
}