npm package: @opencampus/oc-vc-verification-js
Description: OC VC Verification SDK
Author: Animoca Brands
Latest version: 2.0.0

# OpenCampus VC Verification SDK

A comprehensive SDK for verifying Verifiable Credentials (VCs) in React applications, supporting both mainnet and testnet environments.

## 🚀 Features

- BBS+ Verification
- NFT Ownership Verification
- Issuer Validation
- Mainnet and Testnet Support
- React Integration

## 📦 Installation

```
# Using npm
npm install @opencampus/oc-vc-verification-js

# Using yarn# 
yarn add @opencampus/oc-vc-verification-js
```

Compile & build project
```bash
yarn build
```

## 🔧 Usage

### React Integration

1. Set up the Provider

```
import { CredentialProvider } from '@opencampus/oc-vc-verification-js';

function App() {
  return (
    <CredentialProvider OCUser={{ OCId, ethAddress }} opts={{windowMode: 'window' }} sandboxMode={true}>
      <YourApp />
    </CredentialProvider>
  );
}
```

- OCUser: (Required) is an object comprised of `OCId` and `ethAddress` of the user that is current prompted for selecting their VCs. OCUser should be passed in with the following shape
```
{
  OCId: <.edu OCId of the user>,
  ethAddress: <The ethAddress as returned from the connect with OCID process>
}
```
- sandboxMode: (Optional) if it is true, then item is issued in sandbox (testnet) environment, default to false (liveMode)
- windowMode: (Optional) the sdk supports 3 display modes: modal |  tab |  popup. The default display is popup

2. Retrieve Credentials

```
import { CredentialContext } from '@opencampus/oc-vc-verification-js';

const { 
  credentials
} = useContext(CredentialContext);
```

### Javascript integration

1. Simple guidline to integrate with plain Javascript:
- There are two classes, SandboxCredentialSelector & LiveCredentialSelector that would help us to interact with either testnet or mainnet envrionment.

```
import {SandboxCredentialSelector, CredentialSelector} from '@opencampus/oc-vc-verification-js';

let storedCredentials
const updateCreds = credentialState => {
  storedCredentials = credentialState
};

let windowMode = 'modal';
let credentialSelector = new SandboxCredentialSelector(windowMode);
credentialSelector.credentialInfoManager.subscribe(updateCreds);

// call this code when users navigate away from the current page to avoid memory leak
credentialSelector.hide();
```

### 📊 Integrate with verification process

The SDK performs asynchronous verification of credentials received from our website. Each credential's verification result can be accessed using its token ID. Here's how to check verification status:

Access verification results for a specific token

```
import { CredentialContext } from '@opencampus/oc-vc-verification-js';
const { credentials, verificationResults } = useContext(CredentialContext);
const result = verificationResults[tokenId];
```

You can loop through all verification results. Each result contains an array of verifier checks

```
import { CredentialContext } from '@opencampus/oc-vc-verification-js';
const { credentials, verificationResults } = useContext(CredentialContext);
const result = verificationResults[tokenId];

Object.entries(verificationResults).map(([tokenId, result]) => {
  result.verificationResults.map(check => {
    console.log(`${check.verifierName}: ${check.isVerified ? 'Verified' : 'Failed'}`);
  });
});
```

The SDK provides two methods to access credential data:
1. metaData(): Fetches on-chain NFT data

```
const metadata = await credential.metaData();
```

2. credentialData(): Returns comprehensive credential information
We also provide credentialData() that will return both on-chain data and credential data that the sdk received from OCID.


```
  const { metadata, presentationData } = await credential.credentialData();
```

Example usage: 

```
const [metadataMap, setMetadataMap] = useState({});
    
useEffect(() => {
  const fetchAllMetadata = async () => {
    const metadata = {};
    await Promise.all(
      Object.values(credentials).map(async (credential) => {
        try {
          metadata[credential.tokenId] = await credential.metaData();
        } catch (error) {
          console.error('Error fetching metadata:', error);
          metadata[credential.tokenId] = null;
        }
      })
    );

    setMetadataMap(metadata);
  };
    
  fetchAllMetadata();
}, [credentials]);
```


## SDK Interface Reference

### useCredentialContext hook

The `useCredentialContext` hook returns a few useful states and functions:

| Context Value       | Description                                                                                                                                                                                                                   |
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| credentialSelector  | An instance of CredentialSelector that allow you to perform custom control of the selection window. For the credentialSelector has been wired with the provided react components so you should not need to explicitly use it. |
| credentials         | A list of OCCredential instances, each representing a credential that has been selected by the user.                                                                                                                          |
| verificationResults | An instance of VerificationResult.                                                                                                                                                                                            |
| openSelector        | A function that can be called to open the selector window.                                                                                                                                                                    |


### OCCredential

The `OCCredential` object is a useful wrapper around a user selected credential. It encapsulates most complexity around using the selected credential.

#### Instance Values

| Instance value   | Description                                                           |
|------------------|-----------------------------------------------------------------------|
| tokenId          | The tokenId of the corresponding credential NFT                       |
| vcId             | The VC Id of the original Credential                                  |
| presentationData | The payload containing just credential owner's name and email address |


#### Instance Methods

| Instance method  | Description                                                                                                                                                                                                           | Returns                                                                                        |
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| verify()         | Verify this credential via the verifiers.                                                                                                                                                                             | A Promise of VerificationResults                                                               |
| metaData()       | Return the metaData for the credential NFT that corresponds to this credential. This method reads the credential NFT contract for metadata URI and retrieve metadata using the credential's tokenId.                  | A Promise of metadata JSON object                                                              |
| credentialData() | Return both the metadata for the credential NFT and credential holder Name and Email as included in the generated Presentation. For the most part you should just use this method over the `metadata()` method alone. | A Promise returning an object of shape  ``` {    metadata: ...,    presentationData: ... } ``` |

### Verification Results

The `VerificationResult` object contains result from each of the verifiers on a credential selected by user.

Below are the verifiers that are implemented and you would see them in `VerificationResult`

| Verifier Name        | Description                                                                                                                                               | Failure Conditions                                                                                                   |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| BbsPlusVPVerifier    | Verify that the Presentation received has a cryptographically valid proof. That it is derivable from the credential that corresponds to the NFT on-chain. | The received presentation cannot be verified, hence it is not proven to be derived from the credential NFT on chain. |
| IssuerValidVerifier  | Verify that the Issuer that issued the credential is currently a whitelisted and valid issuer according to the DIDRegistry smart contract.                | Either the Issuer is not whitelisted or the Issuer has been revoked.                                                 |
| NftOwnershipVerifier | Verify that the corresponding credential NFT on-chain is owned by the expected owner's Eth wallet address.                                                | Either the credential does not have a corresponding credential NFT on-chain or the owner is not the expected owner.  |
| RevocationVerifier   | Verify that the credential has not been revoked on-chain.                                                                                                 | The credential has been issued once, but has been revoked, therefore is no longer valid.                             |