Skip to content

Commit

Permalink
fix(dids): allow to pass in a key instance when creating a did docume…
Browse files Browse the repository at this point in the history
…nt (#1944)

Signed-off-by: Berend Sliedrecht <sliedrecht@berend.io>
  • Loading branch information
berendsliedrecht committed Jul 16, 2024
1 parent d54decb commit a5235e7
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 52 deletions.
5 changes: 5 additions & 0 deletions .changeset/pretty-spies-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@credo-ts/core': patch
---

Allow to pass in a key instance when registering a DID jwk, key or peer with num algo 0
50 changes: 33 additions & 17 deletions packages/core/src/modules/dids/methods/jwk/JwkDidRegistrar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AgentContext } from '../../../../agent'
import type { KeyType } from '../../../../crypto'
import type { Key, KeyType } from '../../../../crypto'
import type { Buffer } from '../../../../utils'
import type { DidRegistrar } from '../../domain/DidRegistrar'
import type { DidCreateOptions, DidCreateResult, DidDeactivateResult, DidUpdateResult } from '../../types'
Expand All @@ -20,23 +20,38 @@ export class JwkDidRegistrar implements DidRegistrar {
const seed = options.secret?.seed
const privateKey = options.secret?.privateKey

if (!keyType) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type',
},
try {
let key = options.options.key

if (key && (keyType || seed || privateKey)) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Key instance cannot be combined with key type, seed or private key',
},
}
}
}

try {
const key = await agentContext.wallet.createKey({
keyType,
seed,
privateKey,
})
if (keyType) {
key = await agentContext.wallet.createKey({
keyType,
seed,
privateKey,
})
}

if (!key) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type or key instance',
},
}
}

const jwk = getJwkFromKey(key)
const didJwk = DidJwk.fromJwk(jwk)
Expand Down Expand Up @@ -107,7 +122,8 @@ export interface JwkDidCreateOptions extends DidCreateOptions {
did?: never
didDocument?: never
options: {
keyType: KeyType
keyType?: KeyType
key?: Key
}
secret?: {
seed?: Buffer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,32 @@ describe('DidRegistrar', () => {
expect(walletMock.createKey).toHaveBeenCalledWith({ keyType: KeyType.P256, privateKey })
})

it('should return an error state if no key type is provided', async () => {
it('should return an error state if a key instance and key type are both provided', async () => {
const key = await agentContext.wallet.createKey({
keyType: KeyType.P256,
})

const result = await jwkDidRegistrar.create(agentContext, {
method: 'jwk',
options: {
key,
keyType: KeyType.P256,
},
})

expect(JsonTransformer.toJSON(result)).toMatchObject({
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Key instance cannot be combined with key type, seed or private key',
},
})
})

it('should return an error state if no key or key type is provided', async () => {
const result = await jwkDidRegistrar.create(agentContext, {
method: 'jwk',
// @ts-expect-error - key type is required in interface
options: {},
})

Expand All @@ -110,7 +132,7 @@ describe('DidRegistrar', () => {
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type',
reason: 'Missing key type or key instance',
},
})
})
Expand Down
50 changes: 33 additions & 17 deletions packages/core/src/modules/dids/methods/key/KeyDidRegistrar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AgentContext } from '../../../../agent'
import type { KeyType } from '../../../../crypto'
import type { Key, KeyType } from '../../../../crypto'
import type { Buffer } from '../../../../utils'
import type { DidRegistrar } from '../../domain/DidRegistrar'
import type { DidCreateOptions, DidCreateResult, DidDeactivateResult, DidUpdateResult } from '../../types'
Expand All @@ -19,23 +19,38 @@ export class KeyDidRegistrar implements DidRegistrar {
const seed = options.secret?.seed
const privateKey = options.secret?.privateKey

if (!keyType) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type',
},
try {
let key = options.options.key

if (key && (keyType || seed || privateKey)) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Key instance cannot be combined with key type, seed or private key',
},
}
}
}

try {
const key = await agentContext.wallet.createKey({
keyType,
seed,
privateKey,
})
if (keyType) {
key = await agentContext.wallet.createKey({
keyType,
seed,
privateKey,
})
}

if (!key) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type or key instance',
},
}
}

const didKey = new DidKey(key)

Expand Down Expand Up @@ -105,7 +120,8 @@ export interface KeyDidCreateOptions extends DidCreateOptions {
did?: never
didDocument?: never
options: {
keyType: KeyType
keyType?: KeyType
key?: Key
}
secret?: {
seed?: Buffer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,32 @@ describe('DidRegistrar', () => {
expect(walletMock.createKey).toHaveBeenCalledWith({ keyType: KeyType.Ed25519, privateKey })
})

it('should return an error state if no key type is provided', async () => {
it('should return an error state if a key instance and key type are both provided', async () => {
const key = await agentContext.wallet.createKey({
keyType: KeyType.P256,
})

const result = await keyDidRegistrar.create(agentContext, {
method: 'key',
options: {
key,
keyType: KeyType.P256,
},
})

expect(JsonTransformer.toJSON(result)).toMatchObject({
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Key instance cannot be combined with key type, seed or private key',
},
})
})

it('should return an error state if no key or key type is provided', async () => {
const result = await keyDidRegistrar.create(agentContext, {
method: 'key',
// @ts-expect-error - key type is required in interface
options: {},
})

Expand All @@ -74,7 +96,7 @@ describe('DidRegistrar', () => {
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type',
reason: 'Missing key type or key instance',
},
})
})
Expand Down
34 changes: 25 additions & 9 deletions packages/core/src/modules/dids/methods/peer/PeerDidRegistrar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AgentContext } from '../../../../agent'
import type { KeyType } from '../../../../crypto'
import type { Key, KeyType } from '../../../../crypto'
import type { Buffer } from '../../../../utils'
import type { DidRegistrar } from '../../domain/DidRegistrar'
import type { DidCreateOptions, DidCreateResult, DidDeactivateResult, DidUpdateResult } from '../../types'
Expand Down Expand Up @@ -37,22 +37,37 @@ export class PeerDidRegistrar implements DidRegistrar {
const seed = options.secret?.seed
const privateKey = options.secret?.privateKey

if (!keyType) {
let key = options.options.key

if (key && (keyType || seed || privateKey)) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type',
reason: 'Key instance cannot be combined with key type, seed or private key',
},
}
}

const key = await agentContext.wallet.createKey({
keyType,
seed,
privateKey,
})
if (keyType) {
key = await agentContext.wallet.createKey({
keyType,
seed,
privateKey,
})
}

if (!key) {
return {
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type or key instance',
},
}
}

// TODO: validate did:peer document

Expand Down Expand Up @@ -183,7 +198,8 @@ export interface PeerDidNumAlgo0CreateOptions extends DidCreateOptions {
did?: never
didDocument?: never
options: {
keyType: KeyType.Ed25519
keyType?: KeyType
key?: Key
numAlgo: PeerDidNumAlgo.InceptionKeyWithoutDoc
}
secret?: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,33 @@ describe('DidRegistrar', () => {
})
})

it('should return an error state if no key type is provided', async () => {
it('should return an error state if a key instance and key type are both provided', async () => {
const key = await agentContext.wallet.createKey({
keyType: KeyType.P256,
})

const result = await peerDidRegistrar.create(agentContext, {
method: 'peer',
options: {
numAlgo: PeerDidNumAlgo.InceptionKeyWithoutDoc,
key,
keyType: KeyType.P256,
},
})

expect(JsonTransformer.toJSON(result)).toMatchObject({
didDocumentMetadata: {},
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Key instance cannot be combined with key type, seed or private key',
},
})
})

it('should return an error state if no key or key type is provided', async () => {
const result = await peerDidRegistrar.create(agentContext, {
method: 'peer',
// @ts-expect-error - key type is required in interface
options: {
numAlgo: PeerDidNumAlgo.InceptionKeyWithoutDoc,
},
Expand All @@ -74,7 +97,7 @@ describe('DidRegistrar', () => {
didRegistrationMetadata: {},
didState: {
state: 'failed',
reason: 'Missing key type',
reason: 'Missing key type or key instance',
},
})
})
Expand Down

0 comments on commit a5235e7

Please sign in to comment.