Skip to content

Verification Service

The Verification module provides tools to create, present, and verify Verifiable Credentials (VCs) and Verifiable Presentations (VPs) on the IDCHAIN blockchain. It enables selective disclosure, challenge-based verification, and proof validation.

Overview

Verification Service allows developers to:

  • Create Verifiable Presentations (VPs) for sharing credentials.
  • Derive proofs with selective disclosure (include or exclude claims).
  • Verify presentations (with challenge and domain checks).
  • Verify individual credentials.

All verifications use cryptographic checks and on-chain resolution for DIDs, schemas, and credential statuses.

API Reference

Set Presentation

Verification.setPresentation(credential, holder, validUntil, options?): Promise<VerifiablePresentation>

Creates a Verifiable Presentation from a credential, optionally revealing only selected claims.

Parameters:

  • credential (VerifiableCredential): The issued credential to present.
  • holder (HolderOptions): Object containing:
  • uidDocument: Holder's DID Document.
  • signers: Array of UidKeyringPair for signing the presentation.
  • validUntil (Date): Expiration date for the presentation.
  • options (optional):
  • challenge (string): Random challenge for replay protection.
  • includeClaims (string[]): Paths of claims to reveal (e.g., ["/NIK"]).
  • excludeClaims (string[]): Paths of claims to hide.

Returns:

  • VerifiablePresentation: A signed, W3C-compliant presentation.

Example:

const vp = await Verification.setPresentation(
  vc,
  {
    uidDocument: userDid.document,
    signers: [userAccount],
  },
  new Date(Date.now() + 10 * 60 * 1000),
  {
    includeClaims: ["/NIK"], // Only reveal NIK
    challenge: "random-challenge",
  }
);
console.log("Verifiable Presentation:", vp);

Verify Presentation

Verification.verifyPresentation(presentation, options?): Promise<any>

Verifies a Verifiable Presentation, checking its proofs, challenge, and underlying credentials.

Parameters:

  • presentation (VerifiablePresentation): The VP to verify.
  • options (optional):
  • challenge (string): Must match the one used in setPresentation.
  • domain (string): Domain constraint (optional).
  • verifier (Uid): DID of the verifier.
  • proofTypes (string[]): Restrict to specific proof types.
  • proofPurpose (string): Validate proof purpose (e.g., "authentication").
  • now (Date): Custom current time for validation.
  • tolerance (number): Clock tolerance in milliseconds.
  • udiDocument (IUidDocument[]): Required schemas for validation.
  • didResolver (function | UidDocument[]): DID resolver or cache.
  • credentialStatusLoader (function): Loader for credential status.

Returns:

  • object: Verification result (including validity and errors).

Example:

const verificationResult = await Verification.verifyPresentation(vp, {
  challenge: "random-challenge",
  now: new Date(),
});
console.log("Verification Result:", verificationResult);

Full Example

import {
  Verification,
  Credential,
  AccountService,
  DidService,
  fromProperties,
  UidDocumentSchema,
} from "@idchain-sdk";

async function createAndVerifyPresentation() {
  // Prepare accounts, DIDs, and credential (similar steps as in Credential Service)
  const { mnemonic: attesterMnemonic, account: attester } =
    await AccountService.generateAccount();
  const { mnemonic: userMnemonic, account: user } =
    await AccountService.generateAccount();

  const attesterDid = await DidService.createDidAttester(
    attester,
    {
      authentication: { publicKey: attester.publicKey, type: "ed25519" },
      keyAgreement: { publicKey: attester.publicKey, type: "x25519" },
      assertionMethod: { publicKey: attester.publicKey, type: "ed25519" },
      capabilityDelegation: { publicKey: attester.publicKey, type: "ed25519" },
    },
    async ({ data }) => ({
      keyType: "ed25519",
      signature: attester.sign(data),
    })
  );

  const userDid = await DidService.createDidClaimer(
    user,
    {
      authentication: { publicKey: user.publicKey, type: "ed25519" },
    },
    async ({ data }) => ({
      keyType: "ed25519",
      signature: user.sign(data),
    })
  );

  // Create schema and credential
  const schema = fromProperties(
    "KTP Schema",
    {
      NIK: { type: "string" },
      Nama: { type: "string" },
      TTL: { type: "string" },
      status: { type: "string" },
    },
    "V1"
  );
  await UidDocumentSchema.storeSchema(attester, attesterDid.uri, schema);

  const unsignedVc = await Credential.requestAttestation(
    userDid.document.uri,
    schema,
    {
      NIK: "1122334455",
      Nama: "Charlie",
      TTL: "1990-12-01",
      status: "Married",
    },
    attesterDid.uri
  );
  const vc = await Credential.issueAttestation(
    unsignedVc,
    attesterDid,
    attester
  );

  // Create a Verifiable Presentation with selective disclosure
  const vp = await Verification.setPresentation(
    vc,
    { uidDocument: userDid.document, signers: [user] },
    new Date(Date.now() + 5 * 60 * 1000),
    {
      includeClaims: ["/NIK"], // Only reveal NIK
      challenge: "audit-challenge-123",
    }
  );

  // Verify the presentation
  const verification = await Verification.verifyPresentation(vp, {
    challenge: "audit-challenge-123",
    now: new Date(),
  });

  console.log("Verification Result:", verification);
}

Error Handling

  • Invalid challenge: Presentation verification fails if challenge does not match.
  • Expired VP or VC: Returns validation errors if time constraints fail.
  • Invalid proofs: Any tampering with data or proof invalidates verification.
  • Schema mismatch: If cTypes or udiDocument are required and not matched, verification fails.