Skip to content

Commit

Permalink
Merge branch 'master' into DCKW-617-update-examples-for-using-the-mob…
Browse files Browse the repository at this point in the history
…ile-sdk
  • Loading branch information
maycon-mello authored Oct 24, 2024
2 parents 17abe50 + f91eb47 commit 77aa682
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 34 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/docs-push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Push docs to knowledgebase
on:
push:
branches: master
paths:
- "docs/**"
- ".github/workflows/docs-push.yml"

jobs:
Copy-docs:
runs-on: ubuntu-latest

steps:
- name: Checkout source repo
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Checkout destination repo
uses: actions/checkout@v2
with:
repository: docknetwork/knowledgebase-docs
token: ${{ secrets.KNOWLEDGEBASE_PR_TOKEN }}
path: knowledge-base

- name: Copy files
run: |
# Specify the files or directories you want to copy
cp -r docs/* knowledge-base/developer-documentation/wallet-sdk
cp README.md knowledge-base/developer-documentation/wallet-sdk
cp -r examples/ knowledge-base/developer-documentation/wallet-sdk
- name: Get branch name
id: get_branch
run: echo "branch_name=sync/${{ github.event.ref }}_${{github.event.head_commit.id}}"| sed -e "s/refs\///g"| sed -e "s/\/\//\//g" >> $GITHUB_ENV

- name: Commit changes
env:
GH_TOKEN: ${{ secrets.KNOWLEDGEBASE_PR_TOKEN }}
run: |
cd knowledge-base
echo ${{env.branch_name}}
git checkout -b ${{env.branch_name}}
git config user.name "${{ github.event.head_commit.author.name }}"
git config user.email "${{ github.event.head_commit.author.email }}"
# Get the commit message from the merged PR
commit_message="${{ github.event.head_commit.message }}"
git add -A .
git status
git commit -m "Copy files from ${{ github.event.repository.full_name }} branch $branch_name: $commit_message"
# Create PR
git ls-remote --get-url origin
git push -u origin ${{ env.branch_name }}
echo "Creating PR..."
gh pr create \
--body "This PR copies /docs files from ${{ github.event.repository.full_name }}." \
--title "${{ github.event.head_commit.message }}" \
--head "${{ env.branch_name }}" \
--base "main"
echo "Docs successfully pushed to knowledgebase-docs"
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# Dock Wallet SDK

Using [polkadot-js](https://polkadot.js.org/) libraries in React Native is a challenge, due to a lack of WebAssembly support.
The [Wallet SDK](https://github.com/docknetwork/react-native-sdk) enables you to build a Verifiable Credentials wallet inside your app and allows your users to receive, store, and manage their DOCK tokens too. This was built for mobile applications with added support for Polkadot-JS.

To use the wallet-sdk, all you need to do is wrap your app in a `WalletSDKProvider` and start building your wallet.

Using [polkadot-js](https://polkadot.js.org/) libraries in React Native is a challenge, due to the lack of WebAssembly support.
The Dock Wallet SDK handles all the Polkadot Web Assembly in a WebView, sending messages to the React Native thread through a JSON RPC layer.

All you need to do is wrap your app in a `WalletSDKProvider` and start building your Polkadot wallet.
Dock Mobile SDK supports devices that have Android 8.1 or higher and iOS 11 or higher.

## Installation
```js
Expand Down
49 changes: 34 additions & 15 deletions docs/biometric-plugin.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Purpose
# Biometric Plugin

## Purpose

The biometrics plugin provides a way to perform credential verification using the user's biometric data. It is useful to guarantee that only the biometric holder can perform the verification.

# How to trigger a biometric verification
## How to trigger a biometric verification

To trigger a biometric verification, you need to use a verification template that asks for the biometric attributes. Check the following example:

Expand Down Expand Up @@ -51,8 +53,10 @@ The presence of the following fields should trigger the biometric check:
}
```

# How to enable the biometric plugin in the wallet
## How to enable the biometric plugin in the wallet

To enable the biometric plugin in a white-label wallet, you need to edit the following file src/wallet-sdk-configs.ts and add your configuration:

```typescript
import { BiometricsPluginConfigs } from "@docknetwork/wallet-sdk-react-native/lib/default-biometrics-plugin";
export const biometricsPluginConfigs: BiometricsPluginConfigs = {
Expand All @@ -71,29 +75,44 @@ export const biometricsPluginConfigs: BiometricsPluginConfigs = {

```

## Credential expiration

# Credential expiration
Credential expiration allows the biometric service provider to specify a maximum length to the validity of a biometric check credential. If the verifier wants to force a refresh of the biometric check more frequently, the verifier can check the credential creation timestamp during verification to ensure it’s within their business rules.

# Credential types
## Credential types

This plugin uses two types of credentials to perform the biometric verification:

- Enrollment Credential: This optional credential contains the biometric data of the user. The biometric data is stored in the credential subject field and will be used to perform the biometric match.
- Biometric Match Credential: This credential is issued by the biometric plugin after the biometric match. It contains the biometric ID, the issuer, and the creation date. The verifier can use this credential to check if the biometric match was performed recently and by the same issuer, and it will not contain any biometric data.
* Enrollment Credential: This optional credential contains the biometric data of the user. The biometric data is stored in the credential subject field and will be used to perform the biometric match.
* Biometric Match Credential: This credential is issued by the biometric plugin after the biometric match. It contains the biometric ID, the issuer, and the creation date. The verifier can use this credential to check if the biometric match was performed recently and by the same issuer, and it will not contain any biometric data.

## How to bind a biometric to a credential

# How to bind a biometric to a credential
Before issuing a credential, the issuer may request to verify the biometric check credential. If a valid credential does not exist, the wallet will trigger the biometric plugin to confirm the biometric and issue a credential.

The biometric check credential needs a unique binding ID that can only be generated by that specific user. The issuer can then include in the primary credential the biometric ID and biometric issuer as attributes that bind that credential to that holder's biometric.
The biometric check credential needs a unique binding ID that can only be generated by that specific user. The issuer can then include in the primary credential, the biometric ID and biometric issuer as attributes that bind that credential to that holder's biometric.

At the time of verification, the verifier can request the biometric check credential along with the primary credential. If the biometric check credential is recent enough, from the same issuer, and contains the same biometric ID, then the verifier can know it is the same holder presenting the credential.

The biometric ID should not contain the user's actual biometric information. When enrolling a holder in the biometric service, it might be useful to issue an enrollment credential containing the biometric template, the generated biometric ID, and any other needed information to identify a returning user. This credential can be verified to get the user's information before checking their biometric. By storing this information with the holder, it avoids the biometric service having to store that PII outside of the control of the holder. The holder should only share a biometric enrollment credential with the biometric service that issued it.
The biometric ID should not contain the user's actual biometric information. When enrolling a holder in the biometric service, it might be useful to issue an enrolment credential containing the biometric template, the generated biometric ID and any other needed information to identify a returning user. This credential can be verified to get the user's information before checking their biometric. By storing this information with the holder, it avoids the biometric service having to store that PII outside of the control of the holder. The holder should only share a biometric enrollment credential with the biometric service that issued it.

## Using the Biometric Service Plugin

* Create a [Dock API key](../../dock-certs/creating-api-keys-and-webhook-endpoints.md)
* Wrap the Dock API in your mobile API (which is usually protected with an app username / password)
* When a specific install does a biometric check, call your mobile API to issue a biometric credential
* The biometric binding nested attributes in the primary credential should include the ecosystem and biometric issuer alongside the biometric ID
* Your mobile API calls the Dock API to do issuance to the DID
* In order to use the ecosystem definition of the credentials, the Dock API should be used to query the ecosystem that is found in the credential for the “\*biometric check” schema
* Mobile API should include the DID that the credential is pushed to
* This allows the biometric check credential to be managed in the ecosystem where other participants can rely on it and VPI can be enforced
* Biometric Service Plugin monitors credentials received. When a new biometric check credential is received, old ones can be deleted from wallet storage.
* If biometric data should not leave the device, then the biometric service provider plugin can do a local verification of the biometric enrollment credential using the credential SDK. The biometric enrollment credential is managed independent from the ecosystem, as it should only be verified by the biometric provider.

# Adding a custom biometric provider
Adding a custom biometric provider will require the development of the plugin following the interface defined at packages/react-native/lib/default-biometrics-plugin.ts. The plugin should implement the following methods:
## Adding a custom biometric provider

- hasProofOfBiometrics: Checks if the verification template is asking for biometric attributes.
- enrollBiometrics: Enrolls the biometric data.
- matchBiometrics: Performs the biometric match and if it is valid, returns a biometric match credential. It will try to reuse an existing biometric match credential if it is still valid, otherwise it will remove the expired credential and issue a new one.
Adding a custom biometric provider will require the development of the plugin following the interface defined at [packages/react-native/lib/default-biometrics-plugin.ts](https://github.com/docknetwork/react-native-sdk/blob/master/packages/react-native/lib/default-biometrics-plugin.ts). The plugin should implement the following methods:

* hasProofOfBiometrics: Checks if the verification template is asking for biometric attributes.
* enrollBiometrics: Enrolls the biometric data.
* matchBiometrics: Performs the biometric match and if it is valid, returns a biometric match credential. It will try to reuse an existing biometric match credential if it is still valid, otherwise it will remove the expired credential and issue a new one.
14 changes: 9 additions & 5 deletions docs/ecosystem-tools.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Ecosystem Tools

You can find the implementation of ecosystem tools in the following location:

File Path: packages/core/src/ecosystem-tools.ts
File Path: [packages/core/src/ecosystem-tools.ts](https://github.com/docknetwork/react-native-sdk/blob/5dfbcb197b848802478d2f7a697286a8c3c28823/packages/core/src/ecosystem-tools.ts#L4)

## Usage Example

Below is an example demonstrating how to use getEcosystems to retrieve ecosystem information based on an issuer's DID.

Importing the Function
First, ensure you import getEcosystems from the SDK:
Importing the Function First, ensure you import getEcosystems from the SDK:

```js
import {getEcosystems} from '@docknetwork/wallet-sdk-core/src/ecosystem-tools';
Expand All @@ -26,6 +28,7 @@ fetchEcosystemDetails();
```

## Expected Output

When you run the above code, you should expect an output similar to this:

```json
Expand All @@ -37,10 +40,11 @@ When you run the above code, you should expect an output similar to this:
}
}
```

This JSON output contains the details of the ecosystems associated with the given issuerDID.

## Integration Tests

For more examples and usage, please refer to the integration test at:

Test File Path: integration-tests/ecosystem-tools.test.ts
This test file provides comprehensive examples on how to interact with ecosystem tools effectively.
Test File Path: https://github.com/docknetwork/react-native-sdk/blob/master/integration-tests/ecosystem-tools.test.ts This test file provides comprehensive examples on how to interact with ecosystem tools effectively.
19 changes: 18 additions & 1 deletion integration-tests/ecosystem-tools.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {IWallet} from '@docknetwork/wallet-sdk-core/lib/types';
import {closeWallet, getWallet} from './helpers/wallet-helpers';
import {getEcosystems} from '@docknetwork/wallet-sdk-core/src/ecosystem-tools';
import {getEcosystems, getVerifiers} from '@docknetwork/wallet-sdk-core/src/ecosystem-tools';

const biometricCredential = {
'@context': [
Expand Down Expand Up @@ -76,6 +76,7 @@ describe('BBS+ presentations', () => {

const result = await getEcosystems({
issuerDID: biometricCredential.issuer.id,
networkId: 'testnet',
});

console.log(result);
Expand All @@ -95,6 +96,22 @@ describe('BBS+ presentations', () => {
'0xc5671b2d1552db9b47a3501109ddbeb861a55fe3f7a0cb7a26791203abe9fcc8'
].name,
).toBe('clarity partners');

});

it('should fetch verifiers for the given registry', async () => {

const result = await getVerifiers({
trustRegistryId: '0xdbba3dec1cb5523760480d430c3f18d96848f93a95662944a296a1753ef2860d',
schemaId: 'https://schema.dock.io/BankIdentity-V5-1721219465285.json',
networkId: 'testnet',
});

console.log(result);

expect(result.length).toBeGreaterThan(0);
expect(result).toContain('did:dock:5Fv9Gxbf37DdiNrT31zKTM7ryf8H4psoP3XXxtmVuijNiTTS');

});

afterAll(() => closeWallet());
Expand Down
47 changes: 36 additions & 11 deletions packages/core/src/ecosystem-tools.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
import {dockService} from '@docknetwork/wallet-sdk-wasm/src/services/dock';
import {trustRegistryService} from '@docknetwork/wallet-sdk-wasm/src/services/trust-registry';
import assert from 'assert';
import axios from 'axios';


function getApiURL(networkId) {
return networkId === 'mainnet' ? 'https://api.dock.io' : 'https://api-testnet.dock.io';
}

export async function getEcosystems({
issuerDID,
verifierDID,
schemaId,
networkId,
}: {
networkId: string;
issuerDID?: string;
verifierDID?: string;
schemaId?: string;
}) {
await dockService.ensureDockReady();

assert(!!networkId, 'networkId is required');
try {
return await trustRegistryService.getTrustRegistries({issuerDID, verifierDID, schemaId});
// TODO: Use the SDK to fetch ecosystems when it's available
const {data} = await axios.post(`${getApiURL(networkId)}/trust-registries/query`,{
issuerDID,
verifierDID,
schemaId,
})

const registries = {}

data.forEach((registry) => {
registries[registry.id] = registry;
});

return registries;
} catch (error) {
console.log('error', error);
return [];
}
}

export async function getVerifiers({trustRegistryId, issuerDID, schemaId}) {
await dockService.ensureDockReady();
export async function getVerifiers({trustRegistryId, issuerDID, schemaId, networkId}: {
trustRegistryId: string;
issuerDID?: string;
schemaId?: string;
networkId: string;
}) {
assert(!!networkId, 'networkId is required');
assert(!!trustRegistryId, 'trustRegistryId is required');

try {
const verifiers = await trustRegistryService.getTrustRegistryVerifiers({
schemaId,
issuerDID: issuerDID,
trustRegistryId,
});
return verifiers;
// TODO: Use the SDK to fetch verifiers when it's available
const { data } = await axios.get(`${getApiURL(networkId)}/trust-registries/${trustRegistryId}/verifiers?schemaId=${encodeURIComponent(schemaId)}&issuerDID=${issuerDID}`);
return data;
} catch (error) {
console.log('error', error);
return [];
Expand Down

0 comments on commit 77aa682

Please sign in to comment.