Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/dcd 28 sales demo cleanup #24

Merged
merged 29 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c99e971
add clarity partners logo to QR
mike-parkhill Apr 24, 2024
87c1e4a
added get wallet page
mike-parkhill Apr 24, 2024
a5f9a26
fix centering of clarity partners logo under QR code
mike-parkhill Apr 24, 2024
28c0b6d
update dprint and fix format errors
mike-parkhill Apr 26, 2024
2ffd45d
update lock files
mike-parkhill Apr 26, 2024
74c5a8a
wip: adding verified badge to pre-filled input fields
mike-parkhill Apr 30, 2024
954f9fb
ux changes for check-badge
mike-parkhill May 1, 2024
0491888
fix undefined errors on address form
mike-parkhill May 1, 2024
219eca2
use same checkmark for filled fields as for verified credentials
mike-parkhill May 2, 2024
3f0d379
remove console.log entries
mike-parkhill May 3, 2024
eefa668
added download script for proof requests
mike-parkhill May 6, 2024
3fdec79
download ecosystem
mike-parkhill May 6, 2024
b357ffe
download participants and schemas
mike-parkhill May 6, 2024
0ce7e75
download participants and linked schema info
mike-parkhill May 8, 2024
8fc45d1
wip - setup-certs
mike-parkhill May 8, 2024
2c2cc1d
populate dids and profiles for ecosystem
mike-parkhill May 13, 2024
4f02f49
invite participants to ecosystem
mike-parkhill May 14, 2024
4328dcc
add proof templates
mike-parkhill May 14, 2024
ef7a676
all elements of the ecosystem are populated, but issuance is failing …
mike-parkhill May 15, 2024
989144e
add issuer DIDs to env.new
mike-parkhill May 16, 2024
f5b1f30
link proof templates to the right DIDs
mike-parkhill May 16, 2024
aa58ed5
updated readme for configuring Certs dependencies
mike-parkhill May 16, 2024
fb798fd
fix tabs in download script
mike-parkhill May 17, 2024
ff1cc29
fix undefined applicant error
mike-parkhill May 17, 2024
5ab3fb7
fixed spacing in loan form
mike-parkhill May 20, 2024
c7815f5
Readme updates and tidied up sample eco-system files
mike-parkhill May 23, 2024
5490392
ignore all .env files
mike-parkhill May 24, 2024
5bb0891
fix getWallet URL to make sure it's https
mike-parkhill May 24, 2024
730968e
Merge branch 'main' into fix/DCD-28_sales_demo_cleanup
mike-parkhill May 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# misc
.DS_Store
*.pem
.env
.env*

# debug
npm-debug.log*
Expand Down
147 changes: 76 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,89 @@

The Dock Sales Demo showcases the integration of KYC, biometric services, and verifiable credentials to demonstrate the capabilities of Dock's API and wallet. It simulates a customer journey through KYC verification, credential issuance, and verification across various scenarios, emphasizing integration ease and user experience.

## Quotient Wallet

This demo is designed to work with the demo Quotient Credit Union wallet app. Please install it for [iOS](https://apps.apple.com/ca/app/quotient-wallet/id6473549219) or [Android](https://play.google.com/store/apps/details?id=labs.dock.quotient).

### Workflow Steps

1. 🚀 User initiates the KYC process.
2. 🔒 Biometric verification is conducted by scanning a QR code.
3. ✅ Upon successful verification, the user is issued verifiable credentials.
4. 🔍 The user presents the credentials for verification.

*Note: The Dock wallet app, with the biometric service plugin enabled, is required.*

## 🎮 Running the Project

### 📓Prerequisites

- Node.js and npm installed.
- Dock account with API access.

### 🔑 Configuration

### 🛠️ Installation

1. Clone the repo: `git clone <repo_url>`
2. Install dependencies: `npm install` or `yarn`

### Configuring Certs Dependencies

Running this project depends on having an ecosystem, organizational profiles, and proof request templates configured properly in Certs. You can set these up automatically by using the [setup-certs](./scripts/setup-certs.mjs) command. To run it, follow these steps:

1. Configure the `.env` file by setting the following variables
* DOCK_API_KEY - sign into [Certs](https://certs.dock.io/) and generate a test environment key from `Developer -> API Keys`
* DOCK_API_URL=DOCK_API_URL="https://api-testnet.dock.io"
2. Run `yarn setup-certs`
3. This will generate a `.env.new` file populated with the environment variables you need to run the project. Copy this over the `.env` file

For reference the details about the ecosystem and some sample JSON request bodies can be found in the [data/ecosystem-requests](./data/ecosystem-requests/) folder.

## 🧪 Testing the Project Workflow

Before starting, remember to get the Dock Wallet mobile app, with the biometric service plugin enabled, is required. The Dock Wallet app is available on PlayStore or AppStore.

The demo workflow consists of going through the KYC process filling the formularies and scanning each QR code to get authenticated and test the organizations ecosystems.

It's based on an ecosystem called, "Clarity Partners". The ecosystem contains the following organizations:

**Quotient Credit Union:** Create BankId and Credit Score credentials and Apply for an auto loan.

**Equinet:** Create and revoke Credit Score credential and issue a new one.

**Urbanscape:** Apply for an apartment providing your BankId and Credit Score credentials.

**1. Create a Bank account:** On the main page organizations click on “New Bank Account” from Quotient.

Fill the formulary required data and click on “Submit Application”. This will take you to the first QR code we need to scan with the Dock Wallet app using the option “Scan”. This QR code will trigger the biometric verification process on the mobile to get the Biometric credential.

Once QR code verification is successful, you will receive 2 credentials in your Dock Wallet, “Credit Score credential” and “BankId credential”.

**2. Obtain Auto Loan:** On the main page click on “Obtain Auto Loan” from Quotient.

Identify yourself scanning the QR code using your Dock Wallet app and select the required credentials: Biometric, BankId, and Credit Score.

On verification success will automatically fill the fields “First Name, Last Name, Street Address”, from your BankId credential details, then click on “Submit Application” to continue.

On the success page, you will find a second QR code to scan with the Dock Wallet to proof your Credit Score from your credential.

**3. Revoke & Reissue Credit Score:** On the main page click on “Visit Site” from Equinet. This page is the representation of a Credit Score credential history. You can revoke the actual Credit Score credential and issue another with one action. Click on “Revoke and Issue New credential” to test the functionality. Note: you need to complete previous steps to own this credential and revoke it.

**4. Apply for an apartment:** On the main page click on “Visit Site” from Urbanscape. Identify yourself scanning the QR code using your Dock Wallet app and select the required credentials: Biometric, BankId, and Credit Score.

On verification success will automatically fill the fields “First Name, Last Name, Street Address”, from your BankId credential details, then click on “Submit Application” to continue.

On the success page, you will find a second QR code to scan and proof your Credit Score from your credential.

With this, we finish the workflow from the application where we can have an overview of some usage of the decentralized identity and credentials management.

## Resources

- [Dock](https://www.dock.io/)
- [Dock API Documentation](https://docs.api.dock.io/)
- [Next.js](https://nextjs.org/)

# Developer Documentation

## Technologies Used

Expand Down Expand Up @@ -105,74 +180,4 @@ Hooks methods are use in single component `components/qrcode/qr-auth.jsx` with t

The `QrCodeAuthentication` component manages QR code authentication flow. It renders UI elements conditionally based on whether the QR code is verified or not. If not verified, it displays QR code verification UI provided by VerifyQrCode component along with optional descriptive texts before and after. Upon verification, it shows a refresh icon to allow users to retry the authentication process. Additionally, it lists required credentials using CredentialCards component.

## 🎮 Running the Project

### 📓Prerequisites

- Node.js and npm installed.
- Dock account with API access.

### 🔑 Configuration

To configure the project, set up environment variables. Copy the `.env.example` file to a new file named `.env` and fill in the variables:

- `NEXT_PUBLIC_DOCK_API_URL`: URL to the Dock API, set to the testnet endpoint.
- `DOCK_API_TOKEN`: Your API token for authenticating with the Dock API.
- `DOCK_API_DID`: The DID to use for the issuer. You can generate a DID [here](https://certs.dock.io/dids).
- `NEXT_PUBLIC_SERVER_URL`: The URL of your server, defaulting to `http://localhost:3000` for local development.

### Proof-Request Template IDs and Organization Profiles

Create these IDs from [Certs Dock](https://certs.dock.io/). Fill in the template IDs and issuer IDs for your proof requests and organization profiles. These are crucial for the functioning of your verifiable credentials within the demo.

Ensure all these configurations are set properly in your `.env` file before running the project to ensure smooth operation and connectivity to the necessary services.

### 🛠️ Installation and Deployment

1. Clone the repo: `git clone <repo_url>`
2. Install dependencies: `npm install` or `yarn`
3. Start the project: `npm start` or `yarn dev`

## 🧪 Testing the Project Workflow

Before starting, remember to get the Dock Wallet mobile app, with the biometric service plugin enabled, is required. The Dock Wallet app is available on PlayStore or AppStore.

The demo workflow consists of going through the KYC process filling the formularies and scanning each QR code to get authenticated and test the organizations ecosystems.

It's based on 3 ecosystems:

**Quotient:** Get BankId and Credit Score credentials and Apply for an auto loan.

**Equinet:** Revoke Credit Score credential and issue a new one.

**Urbanscape:** Apply for an apartment providing your BankId and Credit Score credentials.

**1. Create a Bank account:** On the main page organizations click on “New Bank Account” from Quotient.

Fill the formulary required data and click on “Submit Application”. This will take you to the first QR code we need to scan with the Dock Wallet app using the option “Scan”. This QR code will trigger the biometric verification process on the mobile to get the Biometric credential.

Once QR code verification is successful, you will receive 2 credentials in your Dock Wallet, “Credit Score credential” and “BankId credential”.

**2. Obtain Auto Loan:** On the main page click on “Obtain Auto Loan” from Quotient.

Identify yourself scanning the QR code using your Dock Wallet app and select the required credentials: Biometric, BankId, and Credit Score.

On verification success will automatically fill the fields “First Name, Last Name, Street Address”, from your BankId credential details, then click on “Submit Application” to continue.

On the success page, you will find a second QR code to scan with the Dock Wallet to proof your Credit Score from your credential.

**3. Revoke & Reissue Credit Score:** On the main page click on “Visit Site” from Equinet. This page is the representation of a Credit Score credential history. You can revoke the actual Credit Score credential and issue another with one action. Click on “Revoke and Issue New credential” to test the functionality. Note: you need to complete previous steps to own this credential and revoke it.

**4. Apply for an apartment:** On the main page click on “Visit Site” from Urbanscape. Identify yourself scanning the QR code using your Dock Wallet app and select the required credentials: Biometric, BankId, and Credit Score.

On verification success will automatically fill the fields “First Name, Last Name, Street Address”, from your BankId credential details, then click on “Submit Application” to continue.

On the success page, you will find a second QR code to scan and proof your Credit Score from your credential.

With this, we finish the workflow from the application where we can have an overview of some usage of the decentralized identity and credentials management.

## Resources

- [Dock](https://www.dock.io/)
- [Dock API Documentation](https://docs.api.dock.io/)
- [Next.js](https://nextjs.org/)
13 changes: 7 additions & 6 deletions components/forms/form-field-address.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Input } from 'components/ui/input';
* @memberof QuotientBankForm, QuotientApplyLoanForm
* @returns React.FC Form Field
*/
const FormFieldAddress = ({ control }) => (
const FormFieldAddress = ({ control, applicant }) => (
<div className='grid gap-2'>
<h2 className='text-lg font-semibold'>What is your home address?</h2>
<div className='grid grid-cols-2 gap-2'>
Expand All @@ -25,7 +25,8 @@ const FormFieldAddress = ({ control }) => (
<FormItem>
<FormLabel>Street Address</FormLabel>
<FormControl>
<Input placeholder="Enter street address" {...field} />
<Input placeholder="Enter street address" {...field} data={applicant?.streetAddress}
/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -48,10 +49,10 @@ const FormFieldAddress = ({ control }) => (
control={control}
name="zipCode"
render={({ field }) => (
<FormItem className='w-10'>
<FormItem className='w-15'>
<FormLabel>Zip Code</FormLabel>
<FormControl>
<Input placeholder="Enter Zip Code" {...field} />
<Input placeholder="Enter Zip Code" {...field} data={applicant?.zipCode} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -63,7 +64,7 @@ const FormFieldAddress = ({ control }) => (
<FormItem className='w-60'>
<FormLabel>City</FormLabel>
<FormControl>
<Input placeholder="Enter city" {...field} />
<Input placeholder="Enter city" {...field} data={applicant?.city} className='flex h-10'/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -75,7 +76,7 @@ const FormFieldAddress = ({ control }) => (
<FormItem className='w-30'>
<FormLabel>State</FormLabel>
<FormControl>
<Input placeholder="Select one" {...field} />
<Input placeholder="Select one" {...field} data={applicant?.state} />
</FormControl>
<FormMessage />
</FormItem>
Expand Down
10 changes: 7 additions & 3 deletions components/forms/form-field-id.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { Separator } from 'components/ui/separator';
* @memberof QuotientBankForm, QuotientApplyLoanForm
* @returns React.FC Form Field
*/
const FormFieldNameAndBirthday = ({ control, dob = false }) => (
const FormFieldNameAndBirthday = ({ control, applicant, dob = false }) => (
<>
<h2 className='font-semibold'>Tell us your full name as it appears on your government issue ID</h2>
<div className='grid grid-cols-2 gap-2'>
Expand All @@ -44,7 +44,9 @@ const FormFieldNameAndBirthday = ({ control, dob = false }) => (
<FormItem>
<FormLabel>First Name</FormLabel>
<FormControl>
<Input placeholder="Enter first Name" {...field} />
<Input placeholder="Enter first Name"
data={applicant.firstName}
{...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -68,7 +70,9 @@ const FormFieldNameAndBirthday = ({ control, dob = false }) => (
<FormItem>
<FormLabel>Last Name</FormLabel>
<FormControl>
<Input placeholder="Enter last Name" {...field} />
<Input placeholder="Enter last Name"
data={applicant.lastName}
{...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand Down
14 changes: 10 additions & 4 deletions components/forms/urbanscape/form-field-applicant.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import {
FormControl,
FormField,
Expand All @@ -9,7 +9,7 @@ import {
import { Input } from 'components/ui/input';
import { BirthdayPicker } from '../form-field-id';

const FormFieldApplicantId = ({ control }) => (
const FormFieldApplicantId = ({ control, applicant }) => (
<>
<div className='grid grid-cols-3 gap-2'>
<FormField
Expand All @@ -19,7 +19,10 @@ const FormFieldApplicantId = ({ control }) => (
<FormItem>
<FormLabel>First Name</FormLabel>
<FormControl>
<Input placeholder="Enter first Name" {...field} />
<Input
placeholder="Enter first Name"
data={applicant.firstName}
{...field}/>
</FormControl>
<FormMessage />
</FormItem>
Expand All @@ -31,7 +34,10 @@ const FormFieldApplicantId = ({ control }) => (
<FormItem>
<FormLabel>Last Name</FormLabel>
<FormControl>
<Input placeholder="Enter last Name" {...field} />
<Input
placeholder="Enter last Name"
data={applicant.lastName}
{...field} />
</FormControl>
<FormMessage />
</FormItem>
Expand Down
2 changes: 1 addition & 1 deletion components/org/quotient/quotient-success.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const QuotientSuccess = ({ title, proofTemplateId, showQrcode = true }) => {
{textFields.benefits}
</p>
<p className='text-justify font-semibold leading-loose mt-5'>
Download the Quotient Mobile App by clicking <Link href='https://play.google.com/store/apps/details?id=com.dockapp&hl=en_US'>
Download the Quotient Mobile App by clicking <Link href='/wallet'>
<a className='text-blue-600' target='_blank' rel='noopener noreferrer'>
this link
</a>
Expand Down
10 changes: 9 additions & 1 deletion components/qrcode/qr-auth.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import Image from 'next/image';
import { Separator } from 'components/ui/separator';
import VerifyQrCode from 'components/qrcode/verify-qr-code';
import qrCodeStore from 'store/qrCodeStore';
Expand Down Expand Up @@ -28,7 +29,14 @@ const QrCodeAuthentication = ({ proofTemplateId, title = '', qrText = '', qrText
)}

<VerifyQrCode proofTemplateId={proofTemplateId} />

<div className='m-auto ta-c relative w-fit'>
<Image
src={'/clarity_partners.png'}
alt='clarity_partners'
width={230}
height={36}
/>
</div>
{(qrTextAfter !== null && qrTextAfter !== '') && (
<div>
<p className='text-start font-semibold mb-5'>{qrTextAfter}</p>
Expand Down
2 changes: 1 addition & 1 deletion components/qrcode/verify-qr-code.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const VerifyQrCode = ({ proofTemplateId }) => {
<div className='valign-middle' style={{ height: '195px', width: '100%' }}>
<div className='ta-c'>
<Loader2 className="h-10 w-10 animate-spin mb-4" />
<h1 className='text-xl font-bold'>Generating Qr code..</h1>
<h1 className='text-xl font-bold'>Generating QR code..</h1>
</div>
</div>
) : (
Expand Down
4 changes: 3 additions & 1 deletion components/ui/form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const useFormField = () => {
return {
id,
name: fieldContext.name,
isVerified: fieldContext.isVerified,
formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
Expand Down Expand Up @@ -69,12 +70,13 @@ const FormLabel = React.forwardRef(({ className, ...props }, ref) => {
FormLabel.displayName = 'FormLabel';

const FormControl = React.forwardRef(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
const { error, formItemId, formDescriptionId, formMessageId, isVerified } = useFormField();

return (
(<Slot
ref={ref}
id={formItemId}
isVerified={isVerified}
aria-describedby={
!error
? `${formDescriptionId}`
Expand Down
29 changes: 19 additions & 10 deletions components/ui/input.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import * as React from 'react';

import React, { useState } from 'react';
import { cn } from 'utils';
import { Check } from 'lucide-react';

const verifiedBadge = <Check className='text-green-600 h-6 w-6' />;

const Input = React.forwardRef(({ className, type, ...props }, ref) => (
(<input
const Input = React.forwardRef(({ className, type, data, ...props }, ref) => (
<div className = {
cn(
'inputDiv flex h-10 w-full rounded-md border px-3 bg-background text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className
)
}>
<input
className= 'w-full h-9 valign-middle border-transparent outline-none focus:outline-none'
type={type}
className={cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
className
)}
ref={ref}
{...props} />)
));
{...props} />

{data?.isVerified && verifiedBadge}
</div>
));

Input.displayName = 'Input';

export { Input };
Loading
Loading