Developer Guide

This document outlines the steps required to configure the schema, set up credentials, and CSV mapping for storage in the registry, and define the HTML template for displaying certificate data.

Backend Developer Guide:

Architecture

Issuance App (Angular)

  1. This is the front end of the platform where users interact.

  2. It handles tasks such as initiating login, bulk uploading data, approving VCs, and performing searches.

Keycloak:

  1. Used for authentication and authorization.

  2. Ensures secure login for users interacting with the issuance app.

Middleware (NestJS):

  1. Backend application.

  2. Handles requests from the Angular app, processes data (e.g., cleaning and sanitization), and interacts with the Sunbird Registry.

  3. Issues VCs and communicates them back to the registry.

Sunbird RC (Registry and Credentials):

  1. A centralized system for storing and managing credentials.

  2. Provides a Search API for retrieving stored VCs or related data.

  3. Stores issued VCs and registry data.

Key Features

  1. Ability to issue Verifiable Credentials (VCs).

  2. It is possible to add new VCs with minimal configuration changes in just two files.

  3. Support for issuing six types of VCs: Income, Caste, Enrollment, Marksheet, Jan Aadhar, and Sports Participation(.

  4. Option to issue new VCs via bulk upload using a CSV file.

  5. VC Maker can preview the uploaded VCs.

  6. VC Checker can preview, approve, or decline the uploaded VCs.

  7. VC Checker can download individual documents or CSV files for selected documentation.

Registry schema creation

  • The Registry Schema follows JSON Schema Draft-07, a popular standard for defining the structure and validation rules of JSON documents.

  • Schema Reference:

  • Creating and Using Schemas

    • Sources for Schema Creation:

      • API Endpoints: Generate a schema dynamically using APIs provided by the Sunbird RC (Registry & Credential).

      • Direct Schema: Place the schema files directly in the server's designated folder.

    • Steps to Create and Use a Schema:

      • Add the Schema: Either through API integration or by uploading it to the server's schema folder.

      • Restart the Server: After uploading or modifying schemas, restart the server.

      • API Generation: Upon restart, the system automatically generates CRUD APIs for the specified entity.

    • Swagger Documentation:

      • The system provides API documentation for the created entity at: {{registry_url}}/swagger-ui.html

Credentials schema creation

The credential schema is based on the JSON-LD specification and adheres to W3C's Verifiable Credentials (VC) standards. These schemas must be publicly accessible for verification, ensuring compliance with W3C standards during credential issuance.

  • Reference to a VC Schema:

  • Following are the steps for issuing the VC

    • Generate the DId {{RC_IDENTITY_API_BASE_URL}}/did/generate

curl --location ' https://your-issuance-registry-instance.com/identity/did/generate' \
--header 'Content-Type: application/json' \
--data-raw '{
    "content": [
        {
            "alsoKnownAs": [
                "tekdi.uba.issuer-2@tekditechnologies.com"
            ],
            "services": [],
            "method": "rcw"
        }
    ]
}'

Add new credentials schema

curl --location ' https://your-issuance-registry-instance.com/schemacredential-schema' \
--header 'Content-Type: application/json' \
--data '{
{Below is the schema}
}
'
  • Copy id from DID generate API response and replace with author

  • {{RC_CREDENTIAL_SCHEMA_API_BASE_URL}}credential-schema

 {
 "schema": {
   "type": "https://w3c-ccg.github.io/vc-json-schemas/",
   "version": "1.0.0",
   "name": "SportsParticipationCertificate",
   "author": "did:rcw:a72659c8-b2c1-476d-bd09-72a0d0a9f779",
   "authored": "2024-11-26T00:22:23.064Z",
   "schema": {
     "$id": "SportsParticipationCertificate",
     "$schema": "https://json-schema.org/draft/2019-09/schema",
     "description": "The holder details as issued here.",
     "type": "object",
     "properties": {
       "studentId": {
         "type": "string",
         "title": "Student Identifier"
       },
       "schoolId": {
         "type": "string",
         "title": "School Identifier"
       },
       "firstName": {
         "type": "string",
         "title": "First Name"
       },
       "middleName": {
         "type": "string",
         "title": "Middle Name"
       },
       "lastName": {
         "type": "string",
         "title": "Last Name"
       },
       "schoolName": {
         "type": "string",
         "title": "School Name"
       },
       "class": {
         "type": "string",
         "title": "Class"
       },
       "addressLine1": {
         "type": "string",
         "title": "Address Line 1"
       },
       "vtc": {
         "type": "string",
         "title": "Village/Town/City"
       },
       "district": {
         "type": "string",
         "title": "District"
       },
       "pin": {
         "type": "string",
         "title": "PIN Code"
       },
       "state": {
         "type": "string",
         "title": "State"
       },
       "country": {
         "type": "string",
         "title": "Country"
       },
       "organizingVenue": {
         "type": "string",
         "title": "Organizing Venue"
       },
       "eventName": {
         "type": "string",
         "title": "Event Name"
       },
       "eventStartDate": {
         "type": "string",
         "title": "Event Start Date"
       },
       "eventEndDate": {
         "type": "string",
         "title": "Event End Date"
       },
       "typeofSport": {
         "type": "string",
         "title": "Type of Sport"
       },
       "rank": {
         "type": "string",
         "title": "Rank"
       },
       "orgName": {
         "type": "string",
         "title": "Organization Name"
       },
       "orgCode": {
         "type": "string",
         "title": "Organization Code"
       },
       "orgType": {
         "type": "string",
         "title": "Organization Type"
       },
       "orgOfficerName": {
         "type": "string",
         "title": "Organization Officer Name"
       },
       "orgOfficerRank": {
         "type": "string",
         "title": "Organization Officer Rank"
       },
       "orgDistrict": {
         "type": "string",
         "title": "Organization District"
       },
       "orgPin": {
         "type": "string",
         "title": "Organization PIN Code"
       },
       "orgState": {
         "type": "string",
         "title": "Organization State"
       },
       "orgCountry": {
         "type": "string",
         "title": "Organization Country"
       },
       "certificateNumber": {
         "type": "string",
         "title": "Certificate Number"
       },
       "certificateNo": {
         "type": "string",
         "title": "Certificate No"
       },
       "certificateId": {
         "type": "string",
         "title": "Certificate Id"
       }
     },
     "required": ["studentId", "firstName", "lastName", "schoolName", "class"],
     "additionalProperties": true
   }
 },
 "tags": ["dev", "sportsParticipation-certificate-credential"],
 "status": "DRAFT"
}

Publish above schema


curl --location --request PUT ' https://your-issuance-registry-instance.com/schemacredential-schema/publish/did:schema:ea280ee8-0f3c-41a9-afa8-2a010267bc0d/1.0.0'

Issue credentials

curl --location ' https://your-issuance-registry-instance.com/credcredentials/issue' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "credential": {
        "@context": [
            "https://www.w3.org/2018/credentials/v1",
            "https://raw.githubusercontent.com/tekdi/tekdi.github.io/refs/heads/main/static/files/vc-schemas/ubi/SportsParticipationCertificate.json"
        ],
        "type": [
            "VerifiableCredential",
            "sportsParticipationCertificate"
        ],
        "issuer": "did:schema:e405fdc1-867b-434b-b868-fbc86e44309c",
        "issuanceDate": "2024-11-28T06:03:16.174Z",
        "expirationDate": "2025-02-08T11:56:27.259Z",
        "credentialSubject": {
            "id": "did:rcw:issuance-uba-bbb1-4e5e-b6cc-8671c2b3df1e",
            "type": "sportsParticipationCertificate",
            "studentId": "S002",
            "schoolId": "2024",
            "firstName": "Emma",
            "middleName": "Louise",
            "lastName": "Smith",
            "schoolName": "Lakewood Academy",
            "class": "9",
            "addressLine1": "456 Oak St",
            "vtc": "Sunset Village",
            "district": "Lakewood",
            "pin": "654321",
            "state": "Texas",
            "country": "USA",
            "organizingVenue": "Opposite Lakewood Mall",
            "eventName": "State Science Fair",
            "eventStartDate": "2024-06-15",
            "eventEndDate": "2024-06-17",
            "typeofSport": "Science",
            "rank": "2",
            "orgName": "Lakewood Academy",
            "orgCode": "LA654321",
            "orgType": "Private",
            "orgOfficerName": "Mr. Brian Carter",
            "orgOfficerRank": "Principal",
            "orgDistrict": "Lakewood",
            "orgPin": "654321",
            "orgState": "Texas",
            "orgCountry": "USA",
            "issuanceDate": "2024-11-27T03:27:09.205Z",
            "certificateNumber": "2024/654321/S002",
            "certificateNo": "2024/654321/S002",
            "status": "pending",
            "osid": "1-dc404664-11b6-49aa-9c2f-a2fdc39c9d14",
            "vctype": "sportsParticipationCertificate/search"
        }
    },
    "credentialSchemaId": {{Schema_id}},
    "credentialSchemaVersion": "1.0.0",
    "tags": [
        "dev",
        "sportsParticipation-certificate-credential"
    ]
}'

Get the issued VC

curl --location ' https://your-issuance-registry-instance.com/credcredentials/did:rcw:2f11f0b2-dbb5-47c1-b2d9-ed6707c425bf' \
--header 'Accept: application/json'

HTML Template creation

Data mapping for New VCs

The application currently supports 6 types of VCs. To add a new VC, you only need to update two files:

  1. transformers.ts:

  • This file maps the bulk-uploaded data before sending it to the registry.

  1. CredsConfig.ts:

  • This file contains configuration details, specifying:

  • The entity where the data will be saved.

  • The credentials to be used for the process.

  • CSV template for the above 6 certificates

  • To introduce the new VC there will be an HTML template and CSV changes.

Installation and Deployment

  1. Pre-requisites

    1. Sunbird RC: Required for registry and credential(v2.0.0-rc1).

    2. Node.js: Ensure version compatibility (Node.js 16.20.2 in this case).

  2. Local Installation

  • Fork and Clone the Repository:

  • Clone the repository: GitHub Repo

  • Check out the main branch.

  • Install Dependencies:

    • Run: npm install

  • Add Environment Variables:

    • Create a .env file in the root directory with the necessary configurations from the example.env file.

  • Start the Application:

    • For development: npm run start:Dev

  1. Deployment

Dockerfile:

A Dockerfile to containerize the application: Dockerfile

Build the Docker Image:

  1. Run: docker build -t issuance_service .

Run the Container:

  1. Run: docker run -p 3399:3399 issuance_service

GitHub Actions Deployment: Deployment file

Troubleshooting

  1. Unable to upload all records from CSV.

  2. Check the middleware server logs

  3. If unable to detect to issue, check the registry error

  4. Unable to issue VCs

  5. Check the middleware server logs it shows the error

  6. If not able to track, see the logs of credentials services

  7. Data mismatch on certificates

  8. Check the data that is going to print the certificate whether its keys match or not with the HTML template.

Future Enhancements

  1. Issuer and approver to have access to the specific issuing entity

  2. Issuing entity creates functionality

  3. End user login, signup, and dashboard to see issued VC

  4. De-duplication of data

  5. Download the sample CSV template option on the issuer side

  6. Bulk decline


Frontend Developer Guide:

Technical Details:

  1. Framework and Libraries:

    1. Angular

  2. UI Frameworks:

    1. Bootstrap and Angular Material for responsive and consistent UI components

  3. Programming Language:

    1. TypeScript: Ensures type safety, better code quality, and maintainability

  4. API Specification:

  5. RESTful APIs:

  6. Endpoint structure:

    1. /registry/api/v1/Examiner/invite

    2. /registry/api/v1/Examiner

    3. /registry/api/v1/marksheet/search(marksheet will be a dynamic document type)

    4. /api/inspector/preview

    5. /registry/api/v1/incomeCertificate/search (incomeCertificate will be a dynamic document type)

    6. /api/examiner/uploadResult

    7. Keyclock Apis for login and logout

  1. Environment Management:

    1. Environment variables are managed via environment.ts and proxy.conf.json files

  2. Tools and Integrations:

    1. IDE: Visual Studio Code

    2. Linting: ESLint and Prettier for code formatting and quality

    3. Extensions: SonarQube for IDE, Codeium: Free AI-powered code acceleration toolkit

6. Installation and Deployment

  1. Prerequisites:

    1. Node js version v16.20.2

      1. Git

    2. Angular - (^10.0.1)

    3. Typescript - 3.9.5

    4. Angular Material - ^(2.5.0)

    5. Bootstrap - ^(4.5.0)

    6. Keyclock-js ^(8.1.0)

  2. Clone the Repository

  3. Install dependencies:

    Npm install

  4. Create an environment configuration file:

    1. environment.ts

    2. baseUrl

Proxy.conf.json

"/registry/api/v1"

"/registry/api"

"/api" "/registry/api/docs"

"/credentials"

"/metrics"

"/bulk/v1"

  1. Start the development server:

    1. npm run start-dev

Future Enhancements

  1. Keycloak UI changes.

  2. End-user registration should be done through the platform.

  3. The homepage could have a better UI design.

  4. Add a preview option to the approved list in the VC checker dashboard.

  5. Logout should be handled through the platform.

Last updated

Was this helpful?