On-Chain KYC

This guide provides the steps and instructions for integrating Privado ID-based KYC verification directly in your frontend application, utilizing the Privado ID verifier API at https://verifier-backend.privado.id.


Prerequisites

Before you begin integrating Privado ID verification, ensure you have the following:

  • A React-based frontend.

  • Frontend access to https://verifier-backend.privado.id for generating QR codes and checking the verification status.

  • The qrcode.react npm package for rendering QR codes.


Integration Steps

Step 1: Set up Frontend Components

The frontend will be responsible for interacting with users, displaying the QR code, and updating the verification status.

1.1 React Components

  • StatusCard: A component that shows the current KYC status (e.g., "Pending", "Verifying", "Approved", or "Failed").

  • QRCodeSection: Displays the QR code generated for the user to scan with their Privado ID wallet.

  • ActionButtons: Provides buttons like "Start KYC" and "Retry" to allow users to interact with the verification process.

// Example for displaying QR code and status
import React, { useState } from 'react';
import { handlePolygonVerification, pollVerificationStatus } from './api'; // Functions to initiate verification and poll status

const KYCPage = () => {
  const [status, setStatus] = useState('pending');
  const [qrCode, setQrCode] = useState(null);
  const [sessionID, setSessionID] = useState(null);

  const startVerification = async () => {
    const result = await handlePolygonVerification();
    setQrCode(result.qrCode);
    setSessionID(result.sessionID);
    setStatus('verifying');
    pollVerificationStatus(result.sessionID, setStatus); // Poll verification status
  };

  return (
    <div>
      <h1>Privado ID KYC Verification</h1>
      <LhStatusCard status={status} />
      {status === 'verifying' && <LhQRCodeSection qrCode={qrCode} />}
      <LhActionButtons onClick={startVerification} />
    </div>
  );
};

1.2 Handle Verification Requests

Use a function to send a POST request to the Privado ID API to generate the QR code.

// Function to handle verification request
export const handlePolygonVerification = async () => {
  const response = await fetch('https://verifier-backend.privado.id/sign-in', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      chainID: "1952959480", - Lumia Testnet
      scope: [
        {
          circuitId: "credentialAtomicQueryMTPV2",
          id: 1734435086,
          query: {
            allowedIssuers: ["*"],
            context: "https://raw.githubusercontent.com/shiva-decrypt/lumai-json/main/lumiav2.jsonld",
            type: "KYC",
            credentialSubject: {
              Kyc_Approved: { "$eq": true }
            }
          }
        }
      ],
      skipClaimRevocationCheck: false
    })
  });

  const data = await response.json();
  return {
    qrCode: data.qrCode,
    sessionID: data.sessionID,
  };
};

Explanation of the body Section in the Request

The body of the request is a JSON object sent to the Privado ID verifier backend. Here's a breakdown of its components:


1. chainID: "XXXXXXX"

  • Specifies the blockchain network used.

  • 1952959480 corresponds to the Lumia Testnet.

  • 994873017 corresponds to the Lumia Mainnet (Prism)


2. scope

  • Purpose: Defines the query parameters and the type of credential to verify.

  • Contains an array of query objects. Each query object includes:

    • circuitId: "credentialAtomicQueryMTPV2"

      • Specifies the type of cryptographic circuit used for verification.

      • In this case, it's credentialAtomicQueryMTPV2, which supports secure and private verification of claims.

    • id: 1734435086

      • A unique identifier for the query.

    • query: Describes the claim or condition to be checked.

      • allowedIssuers: ["*"]

        • Allows credentials from any issuer (*).

      • context:

        • A URL pointing to the JSON-LD schema defining the structure of the credential.

        • In this case, it links to a schema stored in a GitHub repository.

      • type: "KYC"

        • Specifies the type of credential being validated.

      • credentialSubject:

        • Defines the specific conditions the credential must meet.

        • In this example, Kyc_Approved: { "$eq": true } requires that the Kyc_Approved field in the credential is true.


3. skipClaimRevocationCheck: false

  • Ensures that the claim revocation status is verified.

  • If set to true, the verification would skip checking if the claim has been revoked, which might reduce security.


Possible Modifications

1. Customizing Allowed Issuers

  • Instead of allowing any issuer (allowedIssuers: ["*"]), you can specify trusted issuers. Example:

    Copy

    "allowedIssuers": ["did:polygon:abc123", "did:polygon:def456"]

2. Using a Custom Credential Type

  • Change the type from "KYC" to other credential types if needed. Ensure the schema in the context URL matches the new type.

3. Dynamic chainID Selection

  • If your application supports multiple networks, the chainID can be dynamically passed based on the selected environment (e.g., mainnet or testnet).

4. Revocation Check Skipping

  • For faster verification in non-critical use cases, set skipClaimRevocationCheck to true. However, this is not recommended for sensitive processes.

5. Adding Additional Query Conditions

  • You can validate more fields by adding them to the credentialSubject. Example:

    Copy

    "credentialSubject": {
      "Kyc_Approved": { "$eq": true },
      "Age": { "$gte": 18 }
    }

    This ensures the user is at least 18 years old and has passed KYC.

Step 2: Poll Verification Status

After the QR code is generated, you need to periodically check the status of the verification to keep the user updated.

// Function to poll verification status
export const pollVerificationStatus = async (sessionID, setStatus) => {
  const response = await fetch(`https://verifier-backend.privado.id/status?sessionID=${sessionID}`);
  const data = await response.json();

  if (data.status === 'success') {
    setStatus('approved');
  } 

  // Poll every 5 seconds until verification is completed
  if (data.status !== 'approved' && data.status !== 'failed') {
    setTimeout(() => pollVerificationStatus(sessionID, setStatus), 5000);
  }
};

Step 3: Handle User Interaction

Users can interact with the system by clicking the "Start KYC" button to initiate the verification process and retry if needed.

Example UI Components

import { QRCodeSVG } from 'qrcode.react';

export const LhStatusCard = ({ status }) => {
  return (
    <div>
      <h2>Status: {status}</h2>
    </div>
  );
};

export const LhQRCodeSection = ({ qrCode }) => {
  return (
    <div>
    <QRCodeSVG
              value={qrCode}
              size={400}
              level="H"
              className="h-full w-full"
              includeMargin
              bgColor="#f3f4f6"
              fgColor="#4f46e5"
            />
    </div>
  );
};

export const LhActionButtons = ({ onClick }) => {
  return (
    <div>
      <button onClick={onClick}>Start KYC</button>
    </div>
  );
};

Final Steps

  1. Start the KYC Process:

    • The user clicks the “Start KYC” button, triggering the startVerification function.

    • A QR code will be displayed for the user to scan with their Polygon ID wallet.

  2. Track the Verification Status:

    • Once the user scans the QR code, the status will update to "Verifying."

    • The frontend will automatically poll the status every 5 seconds until the status is either "Approved" or "Failed."

  3. Handle Status Changes:

    • Upon successful verification, the status will update to "Approved".

    • If verification fails, the user can click “Retry” to attempt the process again.


Troubleshooting

  • Issue: QR code is not displayed.

    • Solution: Ensure that the API is returning a valid qrCode URL. Verify that your frontend is correctly displaying the image.

  • Issue: Verification fails.

    • Solution: Confirm that the user's Privado ID wallet app is properly configured and connected to the internet.

  • Issue: Status remains "Pending" for too long.

    • Solution: Ensure the sessionID is valid and being correctly used to check the verification status. You may also want to check for any issues with the Privado ID service.


Conclusion

By following this guide, you can integrate Privado ID verification directly into your frontend application, allowing users to verify their KYC status with ease. The process involves generating a QR code, tracking the status, and providing feedback to the user throughout the verification process.

Last updated