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

feat: openid4vc and sd-jwt-vc support #1708

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ module.exports = {
},
},
{
files: ['demo/**'],
files: ['demo/**', 'demo-openid/**'],
rules: {
'no-console': 'off',
},
Expand All @@ -112,6 +112,7 @@ module.exports = {
'jest.*.ts',
'samples/**',
'demo/**',
'demo-openid/**',
'scripts/**',
'**/tests/**',
],
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ build
.vscode
yarn-error.log
.idea
credo-*.tgz
# Keeping this one in for now to prevent accidental
# old build still in the local repository getting pushed
aries-framework-*.tgz
coverage
.DS_Store
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ See [Supported Features](https://credo.js.org/guides/features) on the Credo webs
</td>
</tr>
<tr>
<td>@aries-framework/indy-vdr</td>
<td>@credo-ts/indy-vdr</td>
<td>
<a href="https://npmjs.com/package/@credo-ts/indy-vdr">
<img alt="@credo-ts/indy-vdr version" src="https://img.shields.io/npm/v/@credo-ts/indy-vdr"/>
Expand Down Expand Up @@ -125,10 +125,10 @@ See [Supported Features](https://credo.js.org/guides/features) on the Credo webs
</td>
</tr>
<tr>
<td>@credo-ts/openid4vc-client</td>
<td>@credo-ts/openid4vc</td>
<td>
<a href="https://npmjs.com/package/@credo-ts/openid4vc-client">
<img alt="@credo-ts/openid4vc-client version" src="https://img.shields.io/npm/v/@credo-ts/openid4vc-client"/>
<a href="https://npmjs.com/package/@credo-ts/openid4vc">
<img alt="@credo-ts/openid4vc version" src="https://img.shields.io/npm/v/@credo-ts/openid4vc"/>
</a>
</td>
</tr>
Expand Down Expand Up @@ -171,6 +171,14 @@ See [Supported Features](https://credo.js.org/guides/features) on the Credo webs
</a>
</td>
</tr>
<tr>
<td><s>@credo-ts/openid4vc-client</s> (deprecated in favour of <code>@credo-ts/openid4vc</code>)</td>
<td>
<a href="https://npmjs.com/package/@credo-ts/openid4vc-client">
<img alt="@credo-ts/openid4vc-client version" src="https://img.shields.io/npm/v/@credo-ts/openid4vc-client"/>
</a>
</td>
</tr>
</table>

## Getting Started
Expand Down
89 changes: 89 additions & 0 deletions demo-openid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<h1 align="center"><b>DEMO</b></h1>

This is the Credo OpenID4VC demo. Walk through the Credo flow yourself together with agents Alice and Faber.

Alice, a former student of Faber College, connects with the College, is issued a credential about her degree and then is asked by the College for a proof.

## Features

- ✅ Creating a connection
- ✅ Offering a credential
- ✅ Requesting a proof
- ✅ Sending basic messages

## Getting Started

### Platform Specific Setup

In order to use Credo some platform specific dependencies and setup is required. See our guides below to quickly set up you project with Credo for NodeJS, React Native.

- [NodeJS](https://credo.js.org/guides/getting-started/installation/nodejs)

### Run the demo

These are the steps for running the Credo OpenID4VC demo:

Clone the Credo git repository:

```sh
git clone https://github.com/openwallet-foundation/credo-ts.git
```

Open two different terminals next to each other and in both, go to the demo folder:

```sh
cd credo-ts/demo-openid
```

Install the project in one of the terminals:

```sh
yarn install
```

In the left terminal run Alice:

```sh
yarn alice
```

In the right terminal run Faber:

```sh
yarn faber
```

### Usage

To set up a connection:

- Select 'receive connection invitation' in Alice and 'create connection invitation' in Faber
- Faber will print a invitation link which you then copy and paste to Alice
- You have now set up a connection!

To offer a credential:

- Select 'offer credential' in Faber
- Faber will start with registering a schema and the credential definition accordingly
- You have now send a credential offer to Alice!
- Go to Alice to accept the incoming credential offer by selecting 'yes'.

To request a proof:

- Select 'request proof' in Faber
- Faber will create a new proof attribute and will then send a proof request to Alice!
- Go to Alice to accept the incoming proof request

To send a basic message:

- Select 'send message' in either one of the Agents
- Type your message and press enter
- Message sent!

Exit:

- Select 'exit' to shutdown the agent.

Restart:

- Select 'restart', to shutdown the current agent and start a new one
36 changes: 36 additions & 0 deletions demo-openid/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "afj-demo-openid",
"version": "1.0.0",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/openwallet-foundation/credo-ts",
"directory": "demo-openid"
},
"license": "Apache-2.0",
"scripts": {
"issuer": "ts-node src/IssuerInquirer.ts",
"holder": "ts-node src/HolderInquirer.ts",
"verifier": "ts-node src/VerifierInquirer.ts",
"refresh": "rm -rf ./node_modules ./yarn.lock && yarn"
},
"dependencies": {
"@hyperledger/anoncreds-nodejs": "^0.2.0-dev.9",
"@hyperledger/aries-askar-nodejs": "^0.2.0-dev.6",
"@hyperledger/indy-vdr-nodejs": "^0.2.0-dev.6",
"express": "^4.18.1",
"inquirer": "^8.2.5"
},
"devDependencies": {
"@credo-ts/openid4vc": "*",
"@credo-ts/askar": "*",
"@credo-ts/core": "*",
"@credo-ts/node": "*",
"@types/express": "^4.17.13",
"@types/figlet": "^1.5.4",
"@types/inquirer": "^8.2.6",
"clear": "^0.1.0",
"figlet": "^1.5.2",
"ts-node": "^10.4.0"
}
}
61 changes: 61 additions & 0 deletions demo-openid/src/BaseAgent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import type { InitConfig, KeyDidCreateOptions, ModulesMap, VerificationMethod } from '@credo-ts/core'
import type { Express } from 'express'

import { Agent, DidKey, HttpOutboundTransport, KeyType, TypedArrayEncoder } from '@credo-ts/core'
import { HttpInboundTransport, agentDependencies } from '@credo-ts/node'
import express from 'express'

import { greenText } from './OutputClass'

export class BaseAgent<AgentModules extends ModulesMap> {
public app: Express
public port: number
public name: string
public config: InitConfig
public agent: Agent<AgentModules>
public did!: string
public didKey!: DidKey
public kid!: string
public verificationMethod!: VerificationMethod

public constructor({ port, name, modules }: { port: number; name: string; modules: AgentModules }) {
this.name = name
this.port = port
this.app = express()

const config = {
label: name,
walletConfig: { id: name, key: name },
} satisfies InitConfig

this.config = config

this.agent = new Agent({ config, dependencies: agentDependencies, modules })

const httpInboundTransport = new HttpInboundTransport({ app: this.app, port: this.port })
const httpOutboundTransport = new HttpOutboundTransport()

this.agent.registerInboundTransport(httpInboundTransport)
this.agent.registerOutboundTransport(httpOutboundTransport)
}

public async initializeAgent(secretPrivateKey: string) {
await this.agent.initialize()

const didCreateResult = await this.agent.dids.create<KeyDidCreateOptions>({
method: 'key',
options: { keyType: KeyType.Ed25519 },
secret: { privateKey: TypedArrayEncoder.fromString(secretPrivateKey) },
})

this.did = didCreateResult.didState.did as string
this.didKey = DidKey.fromDid(this.did)
this.kid = `${this.did}#${this.didKey.key.fingerprint}`

const verificationMethod = didCreateResult.didState.didDocument?.dereferenceKey(this.kid, ['authentication'])
if (!verificationMethod) throw new Error('No verification method found')
this.verificationMethod = verificationMethod

console.log(greenText(`\nAgent ${this.name} created!\n`))
}
}
55 changes: 55 additions & 0 deletions demo-openid/src/BaseInquirer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { prompt } from 'inquirer'

import { Title } from './OutputClass'

export enum ConfirmOptions {
Yes = 'yes',
No = 'no',
}

export class BaseInquirer {
public optionsInquirer: { type: string; prefix: string; name: string; message: string; choices: string[] }
public inputInquirer: { type: string; prefix: string; name: string; message: string; choices: string[] }

public constructor() {
this.optionsInquirer = {
type: 'list',
prefix: '',
name: 'options',
message: '',
choices: [],
}

this.inputInquirer = {
type: 'input',
prefix: '',
name: 'input',
message: '',
choices: [],
}
}

public inquireOptions(promptOptions: string[]) {
this.optionsInquirer.message = Title.OptionsTitle
this.optionsInquirer.choices = promptOptions
return this.optionsInquirer
}

public inquireInput(title: string) {
this.inputInquirer.message = title
return this.inputInquirer
}

public inquireConfirmation(title: string) {
this.optionsInquirer.message = title
this.optionsInquirer.choices = [ConfirmOptions.Yes, ConfirmOptions.No]
return this.optionsInquirer
}

public async inquireMessage() {
this.inputInquirer.message = Title.MessageTitle
const message = await prompt([this.inputInquirer])

return message.input[0] === 'q' ? null : message.input
}
}
Loading
Loading