Skip to content

Commit

Permalink
feat(did-provider-jwk): add did:jwk method support (#1128)
Browse files Browse the repository at this point in the history
  • Loading branch information
tadejpodrekar committed Feb 24, 2023
1 parent 19cccc1 commit 0a22d9c
Show file tree
Hide file tree
Showing 19 changed files with 617 additions and 0 deletions.
5 changes: 5 additions & 0 deletions __tests__/localAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { EthrDIDProvider } from '../packages/did-provider-ethr/src'
import { WebDIDProvider } from '../packages/did-provider-web/src'
import { getDidKeyResolver, KeyDIDProvider } from '../packages/did-provider-key/src'
import { getDidPkhResolver, PkhDIDProvider } from '../packages/did-provider-pkh/src'
import { getDidJwkResolver, JwkDIDProvider } from '../packages/did-provider-jwk/src'
import { DIDComm, DIDCommHttpTransport, DIDCommMessageHandler, IDIDComm } from '../packages/did-comm/src'
import {
ISelectiveDisclosure,
Expand Down Expand Up @@ -201,6 +202,9 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
'did:pkh': new PkhDIDProvider({
defaultKms: 'local',
}),
'did:jwk': new JwkDIDProvider({
defaultKms: 'local',
}),
'did:fake': new FakeDidProvider(),
},
}),
Expand All @@ -219,6 +223,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
...webDidResolver(),
...getDidKeyResolver(),
...getDidPkhResolver(),
...getDidJwkResolver(),
...new FakeDidResolver(() => agent).getDidFakeResolver(),
}),
new DataStore(dbConnection),
Expand Down
5 changes: 5 additions & 0 deletions __tests__/localJsonStoreAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { EthrDIDProvider } from '../packages/did-provider-ethr/src'
import { WebDIDProvider } from '../packages/did-provider-web/src'
import { getDidKeyResolver, KeyDIDProvider } from '../packages/did-provider-key/src'
import { getDidPkhResolver, PkhDIDProvider } from '../packages/did-provider-pkh/src'
import { getDidJwkResolver, JwkDIDProvider } from '../packages/did-provider-jwk/src'
import { DIDComm, DIDCommMessageHandler, IDIDComm } from '../packages/did-comm/src'
import {
ISelectiveDisclosure,
Expand Down Expand Up @@ -164,6 +165,9 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
'did:pkh': new PkhDIDProvider({
defaultKms: 'local',
}),
'did:jwk': new JwkDIDProvider({
defaultKms: 'local',
}),
'did:fake': new FakeDidProvider(),
},
}),
Expand All @@ -173,6 +177,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
...webDidResolver(),
...getDidKeyResolver(),
...getDidPkhResolver(),
...getDidJwkResolver(),
...new FakeDidResolver(() => agent).getDidFakeResolver(),
}),
}),
Expand Down
5 changes: 5 additions & 0 deletions __tests__/localMemoryStoreAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { EthrDIDProvider } from '../packages/did-provider-ethr/src'
import { WebDIDProvider } from '../packages/did-provider-web/src'
import { getDidKeyResolver, KeyDIDProvider } from '../packages/did-provider-key/src'
import { getDidPkhResolver, PkhDIDProvider } from '../packages/did-provider-pkh/src'
import { getDidJwkResolver, JwkDIDProvider } from '../packages/did-provider-jwk/src'
import { DIDComm, DIDCommMessageHandler, IDIDComm } from '../packages/did-comm/src'
import {
ISelectiveDisclosure,
Expand Down Expand Up @@ -161,6 +162,9 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
'did:pkh': new PkhDIDProvider({
defaultKms: 'local',
}),
'did:jwk': new JwkDIDProvider({
defaultKms: 'local',
}),
'did:fake': new FakeDidProvider(),
},
}),
Expand All @@ -169,6 +173,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
...webDidResolver(),
...getDidKeyResolver(),
...getDidPkhResolver(),
...getDidJwkResolver(),
...new FakeDidResolver(() => agent).getDidFakeResolver(),
}),
new DataStore(dbConnection),
Expand Down
5 changes: 5 additions & 0 deletions __tests__/restAgent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { EthrDIDProvider } from '../packages/did-provider-ethr/src'
import { WebDIDProvider } from '../packages/did-provider-web/src'
import { getDidKeyResolver, KeyDIDProvider } from '../packages/did-provider-key/src'
import { getDidPkhResolver, PkhDIDProvider } from '../packages/did-provider-pkh/src'
import { getDidJwkResolver, JwkDIDProvider } from '../packages/did-provider-jwk/src'
import { DIDComm, DIDCommHttpTransport, DIDCommMessageHandler, IDIDComm } from '../packages/did-comm/src'
import {
ISelectiveDisclosure,
Expand Down Expand Up @@ -191,6 +192,9 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
'did:pkh': new PkhDIDProvider({
defaultKms: 'local',
}),
'did:jwk': new JwkDIDProvider({
defaultKms: 'local',
}),
'did:fake': new FakeDidProvider(),
},
}),
Expand All @@ -201,6 +205,7 @@ const setup = async (options?: IAgentOptions): Promise<boolean> => {
// key: getUniversalResolver(), // resolve using remote resolver... when uniresolver becomes more stable,
...getDidKeyResolver(),
...getDidPkhResolver(),
...getDidJwkResolver(),
...new FakeDidResolver(() => serverAgent as TAgent<IDIDManager>).getDidFakeResolver(),
}),
}),
Expand Down
71 changes: 71 additions & 0 deletions __tests__/shared/didManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,77 @@ export default (testContext: {
expect(identifier.controllerKeyId).toEqual(identifier.keys[0].kid)
})

it('should create identifier using did:jwk', async () => {
// keyType supports 'Secp256k1', 'Secp256r1', 'Ed25519', 'X25519'
const keyType = 'Ed25519'
identifier = await agent.didManagerCreate({
provider: 'did:jwk',
options: {
keyType,
}
})
expect(identifier.provider).toEqual('did:jwk')
expect(identifier.keys[0].type).toEqual(keyType)
expect(identifier.controllerKeyId).toEqual(identifier.keys[0].kid)
})
it('should create identifier using did:jwk with an imported key', async () => {
// keyType supports 'Secp256k1', 'Secp256r1', 'Ed25519', 'X25519'
const keyType = 'Ed25519'
identifier = await agent.didManagerCreate({
provider: 'did:jwk',
options: {
keyType,
privateKeyHex: 'f3157fbbb356a0d56a84a1a9752f81d0638cce4153168bd1b46f68a6e62b82b0f3157fbbb356a0d56a84a1a9752f81d0638cce4153168bd1b46f68a6e62b82b0',
}
})
expect(identifier.provider).toEqual('did:jwk')
expect(identifier.keys[0].type).toEqual(keyType)
expect(identifier.controllerKeyId).toEqual(identifier.keys[0].kid)
})
it('should create identifier using did:jwk with a default imported key', async () => {
// keyType supports 'Secp256k1', 'Secp256r1', 'Ed25519', 'X25519'
const keyType = 'Secp256k1'
identifier = await agent.didManagerCreate({
provider: 'did:jwk',
options: {
privateKeyHex: 'f3157fbbb356a0d56a84a1a9752f81d0638cce4153168bd1b46f68a6e62b82b0',
}
})
expect(identifier.provider).toEqual('did:jwk')
expect(identifier.keys[0].type).toEqual(keyType)
expect(identifier.controllerKeyId).toEqual(identifier.keys[0].kid)
})
it('should throw error for invalid privateKEyHex', async () => {
await expect( agent.didManagerCreate({
provider: 'did:jwk',
options: {
privateKeyHex: '1234',
}
})).rejects.toThrow()
expect(identifier.provider).toEqual('did:jwk')
})
it('should throw error for invalid keyUse parameter', async () => {
await expect( agent.didManagerCreate({
provider: 'did:jwk',
options: {
keyType: 'Secp256k1',
keyUse: 'signing',
}
})).rejects.toThrow('illegal_argument: Key use must be sig or enc')
expect(identifier.provider).toEqual('did:jwk')
})
it('should throw error for invalid Ed25519 key use', async () => {
await expect( agent.didManagerCreate({
provider: 'did:jwk',
alias: 'test1',
options: {
keyType: 'Ed25519',
keyUse: 'enc',
}
})).rejects.toThrow('illegal_argument: Ed25519 keys cannot be used for encryption')
expect(identifier.provider).toEqual('did:jwk')
})

it('should throw error for existing alias provider combo', async () => {
await expect(
agent.didManagerCreate({
Expand Down
15 changes: 15 additions & 0 deletions __tests__/shared/resolveDid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ export default (testContext: {
//let cred = await agent.createVerifiableCredential()
});

it('should resolve did:jwk', async () => {
let identifier: IIdentifier = await agent.didManagerCreate({
provider: 'did:jwk',
// keyType supports 'Secp256k1', 'Secp256r1', 'Ed25519', 'X25519'
options: {
keyType: "Ed25519"
}
})
const result = await agent.resolveDid({ didUrl: identifier.did})
const didDoc = result.didDocument
expect(didDoc?.id).toEqual(identifier.did)
expect(result).toHaveProperty('didDocumentMetadata')
expect(result).toHaveProperty('didResolutionMetadata')
});

it('should resolve imported fake did', async () => {
const did = 'did:fake:myfakedid'
await agent.didManagerImport({
Expand Down
29 changes: 29 additions & 0 deletions __tests__/shared/verifiableDataJWT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,35 @@ export default (testContext: {
expect(payload.vc.credentialSubject.id).not.toBeDefined()
})

it('should create verifiable credential (simple) using did:jwk identifier', async () => {
const ident = await agent.didManagerCreate({
kms: 'local',
provider: 'did:jwk',
})
const verifiableCredential = await agent.createVerifiableCredential({
credential: {
issuer: { id: ident.did },
type: ['Example'],
credentialSubject: {
id: 'did:web:example.com',
you: 'Rock',
},
},
proofFormat: 'jwt',
})
const verifyResult = await agent.verifyCredential({credential: verifiableCredential})

expect(verifyResult.verified).toBe(true)
expect(verifiableCredential).toHaveProperty('proof.jwt')
expect(verifiableCredential).toHaveProperty('issuanceDate')
expect(verifiableCredential['@context']).toEqual(['https://www.w3.org/2018/credentials/v1'])
expect(verifiableCredential['type']).toEqual(['VerifiableCredential', 'Example'])

const token = verifiableCredential.proof.jwt
const { payload } = decodeJWT(token)
expect(payload.vc.credentialSubject.id).not.toBeDefined()
})

it('should create verifiable credential keeping original fields', async () => {
expect.assertions(5)
const verifiableCredential = await agent.createVerifiableCredential({
Expand Down
4 changes: 4 additions & 0 deletions packages/did-provider-jwk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Veramo did:jwk provider

This package contains an implementation of `AbstractIdentifierProvider` for the `did:jwk` method, according to the [specification](https://github.com/quartzjer/did-jwk/blob/main/spec.md).
This enables creation and control of `did:jwk` entities.
18 changes: 18 additions & 0 deletions packages/did-provider-jwk/api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"apiReport": {
"enabled": true,
"reportFolder": "./api",
"reportTempFolder": "./api"
},

"docModel": {
"enabled": true,
"apiJsonFilePath": "./api/<unscopedPackageName>.api.json"
},

"dtsRollup": {
"enabled": false
},
"mainEntryPointFilePath": "<projectFolder>/build/index.d.ts"
}
39 changes: 39 additions & 0 deletions packages/did-provider-jwk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@veramo/did-provider-jwk",
"version": "5.0.0",
"description": "Veramo plugin that can enable creation and control of did:jwk identifiers.",
"main": "build/index.js",
"types": "build/index.d.ts",
"exports": "./build/index.js",
"scripts": {
"build": "tsc",
"extract-api": "node ../cli/bin/veramo.js dev extract-api"
},
"dependencies": {
"@veramo/core-types": "^5.0.0",
"@veramo/did-manager": "^5.0.0",
"@veramo/utils": "^5.0.0",
"debug": "^4.3.3",
"did-resolver": "^4.0.1",
"elliptic": "^6.5.4"
},
"devDependencies": {
"@types/debug": "4.1.7",
"@types/elliptic": "6.4.14",
"typescript": "4.9.4"
},
"author": "Tadej Podrekar",
"license": "Apache-2.0",
"keywords": [],
"files": [
"build/**/*",
"src/**/*",
"README.md",
"LICENSE"
],
"type": "module",
"moduleDirectories": [
"node_modules",
"src"
]
}
9 changes: 9 additions & 0 deletions packages/did-provider-jwk/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Provides `did:jwk` {@link @veramo/did-provider-jwk#JwkDIDProvider | identifier provider } for the
* {@link @veramo/did-manager#DIDManager}
*
* @packageDocumentation
*/
export { JwkDIDProvider } from './jwk-did-provider.js'
export { getDidJwkResolver } from './resolver.js'
export * from './types/jwk-provider-types.js'
Loading

0 comments on commit 0a22d9c

Please sign in to comment.