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
Sunbird RC (registry and credentials)
Issuance

Issuance App (Angular)
This is the front end of the platform where users interact.
It handles tasks such as initiating login, bulk uploading data, approving VCs, and performing searches.
Keycloak:
Used for authentication and authorization.
Ensures secure login for users interacting with the issuance app.
Middleware (NestJS):
Backend application.
Handles requests from the Angular app, processes data (e.g., cleaning and sanitization), and interacts with the Sunbird Registry.
Issues VCs and communicates them back to the registry.
Sunbird RC (Registry and Credentials):
A centralized system for storing and managing credentials.
Provides a Search API for retrieving stored VCs or related data.
Stores issued VCs and registry data.
Key Features
Ability to issue Verifiable Credentials (VCs).
It is possible to add new VCs with minimal configuration changes in just two files.
Support for issuing six types of VCs: Income, Caste, Enrollment, Marksheet, Jan Aadhar, and Sports Participation(.
Option to issue new VCs via bulk upload using a CSV file.
VC Maker can preview the uploaded VCs.
VC Checker can preview, approve, or decline the uploaded VCs.
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:
You can access a sample schema here: Marksheet Schema on GitHub
- 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
To view the generated vc preview we are using an HTML template and it can be downloaded too from the frontend application.
Below is the HTML template ref:https://github.com/tekdi/ubi-vc-issuance-mw/blob/main/template/marksheet.html
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:
transformers.ts:
This file maps the bulk-uploaded data before sending it to the registry.
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
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
Deployment
Dockerfile:
A Dockerfile to containerize the application: Dockerfile
Build the Docker Image:
Run: docker build -t issuance_service .
Run the Container:
Run: docker run -p 3399:3399 issuance_service
GitHub Actions Deployment: Deployment file
Troubleshooting
Unable to upload all records from CSV.
Check the middleware server logs
If unable to detect to issue, check the registry error
Unable to issue VCs
Check the middleware server logs it shows the error
If not able to track, see the logs of credentials services
Data mismatch on certificates
Check the data that is going to print the certificate whether its keys match or not with the HTML template.
Future Enhancements
Issuer and approver to have access to the specific issuing entity
Issuing entity creates functionality
End user login, signup, and dashboard to see issued VC
De-duplication of data
Download the sample CSV template option on the issuer side
Bulk decline
Frontend Developer Guide:
Technical Details:
Framework and Libraries:
Angular
UI Frameworks:
Bootstrap and Angular Material for responsive and consistent UI components
Programming Language:
TypeScript: Ensures type safety, better code quality, and maintainability
API Specification:
RESTful APIs:
Endpoint structure:
/registry/api/v1/Examiner/invite
/registry/api/v1/Examiner
/registry/api/v1/marksheet/search(marksheet will be a dynamic document type)
/api/inspector/preview
/registry/api/v1/incomeCertificate/search (incomeCertificate will be a dynamic document type)
/api/examiner/uploadResult
Keyclock Apis for login and logout
Environment Management:
Environment variables are managed via environment.ts and proxy.conf.json files
Tools and Integrations:
IDE: Visual Studio Code
Linting: ESLint and Prettier for code formatting and quality
Extensions: SonarQube for IDE, Codeium: Free AI-powered code acceleration toolkit
6. Installation and Deployment
Prerequisites:
Node js version v16.20.2
Git
Angular - (^10.0.1)
Typescript - 3.9.5
Angular Material - ^(2.5.0)
Bootstrap - ^(4.5.0)
Keyclock-js ^(8.1.0)
Clone the Repository
Install dependencies:
Npm install
Create an environment configuration file:
environment.ts
baseUrl
Proxy.conf.json
"/registry/api/v1"
"/registry/api"
"/api" "/registry/api/docs"
"/credentials"
"/metrics"
"/bulk/v1"
Start the development server:
npm run start-dev
Future Enhancements
Keycloak UI changes.
End-user registration should be done through the platform.
The homepage could have a better UI design.
Add a preview option to the approved list in the VC checker dashboard.
Logout should be handled through the platform.
Last updated
Was this helpful?