๐ค Verification
In this section, you play the role of a Verifier that does the following:
- Take a
Presentation
object supplied by a Claimer - Verify that its data is correct
- Verify that the attestation is valid, i.e., its hash exists on-chain and the attestation has not been revoked
- Verify that the Claimer sending the
Credential
owns it
The Claimer uses a Credential to create the Presentation
object.
Unlike the credential, a Presentation
can hide some attributes that are not required by the Verifier and can contain a claimer-signed challenge.
A Presentation
also contains a proof that the Claimer owns the credential.
Create Presentationโ
A Claimer needs to send more than a credential, as they also need to prove ownership of the credential. A Claimer does this by creating a presentation and signing the Verifier's challenge.
- Typescript
- Javascript
import * as Kilt from '@kiltprotocol/sdk-js'
export async function createPresentation(
credential: Kilt.ICredential,
signCallback: Kilt.SignCallback,
challenge?: string
): Promise<Kilt.ICredentialPresentation> {
// Create the presentation from credential, DID and challenge.
return Kilt.Credential.createPresentation({
credential,
signCallback,
challenge
})
}
# loading code...
The createPresentation
method returns a presentation, taking the credential, a callback to sign data, and the Verifier's challenge as input.
Verifyโ
The verification code exposes the getChallenge
method which returns a random and unique challenge for the Claimer to sign.
This unique challenge is used to prove ownership.
- Typescript
- Javascript
import { config as envConfig } from 'dotenv'
import * as Kilt from '@kiltprotocol/sdk-js'
import { createPresentation } from './claimer/createPresentation'
import { generateKeypairs } from './claimer/generateKeypairs'
import { generateLightDid } from './claimer/generateLightDid'
function getChallenge(): string {
return Kilt.Utils.UUID.generate()
}
// Verifies validity, ownership & attestation.
async function verifyPresentation(
presentation: Kilt.ICredentialPresentation,
challenge: string,
trustedAttesterUris: Kilt.DidUri[]
): Promise<boolean> {
Kilt.ConfigService.get('api')
try {
const { revoked, attester } = await Kilt.Credential.verifyPresentation(
presentation,
{ challenge }
)
if (revoked) {
return false
}
// Returns true if no trusted attester URI is provided or, if it is, if it matches the one that issued the presented credential.
return trustedAttesterUris.includes(attester)
} catch {
return false
}
}
export async function verificationFlow(
credential: Kilt.ICredential,
signCallback: Kilt.SignCallback,
trustedAttesterUris: Kilt.DidUri[] = []
) {
// Verifier sends a unique challenge to the claimer ๐
const challenge = getChallenge()
// Create a presentation and send it to the verifier ๐
const presentation = await createPresentation(
credential,
signCallback,
challenge
)
// The verifier checks the presentation.
const isValid = await verifyPresentation(
presentation,
challenge,
trustedAttesterUris
)
if (isValid) {
console.log('Verification successful! You are allowed to enter the club ๐')
} else {
console.log('Verification failed! ๐ซ')
}
}
// Don't execute if this is imported by another file.
if (require.main === module) {
;(async () => {
envConfig()
try {
await Kilt.connect(process.env.WSS_ADDRESS as string)
const claimerDidMnemonic = process.env.CLAIMER_DID_MNEMONIC as string
const { authentication } = generateKeypairs(claimerDidMnemonic)
const claimerDid = generateLightDid(claimerDidMnemonic)
const attesterDid = process.env.ATTESTER_DID_URI as Kilt.DidUri
// Load credential and claimer DID
const credential = JSON.parse(process.env.CLAIMER_CREDENTIAL as string)
await verificationFlow(
credential,
async ({ data }) => ({
signature: authentication.sign(data),
keyType: authentication.type,
keyUri: `${claimerDid.uri}${claimerDid.authentication[0].id}`
}),
[attesterDid]
)
} catch (e) {
console.log('Error in the verification flow')
throw e
}
})()
}
# loading code...
The verifyPresentation
method performs the actual verification, taking a presentation and the Claimer's challenge as input.
Runโ
Run the code from the command line:
- Typescript
- Javascript
yarn ts-node verify.ts
node verify.js
That's it! All done :-)