Skip to content

Commit

Permalink
Did keys (#26)
Browse files Browse the repository at this point in the history
* feat(did): parse identifier from document id.

* feat(did): backup and restore did keys
  • Loading branch information
zzcwoshizz committed Dec 3, 2022
1 parent 4afa955 commit bfb9914
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 9 deletions.
3 changes: 3 additions & 0 deletions packages/did/src/did/details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type { DidKeys, IDidDetails, KeyRelationship, SignedData } from '../types
import { assert } from '@polkadot/util';

import { base58Encode } from '@zcloak/crypto';
import { parseDid } from '@zcloak/did-resolver/parseDid';

import { DidKeyring } from './keyring';

Expand All @@ -34,6 +35,7 @@ export function typeTransform(type: KeypairType): VerificationMethodType {

export abstract class DidDetails extends DidKeyring implements IDidDetails {
public id: DidUrl;
public identifier: string;
public controller: Set<DidUrl>;
public keyRelationship: Map<DidUrl, KeyRelationship>;
public authentication?: Set<DidUrl>;
Expand All @@ -56,6 +58,7 @@ export abstract class DidDetails extends DidKeyring implements IDidDetails {
}: IDidDetails) {
super();
this.id = id;
this.identifier = parseDid(id).identifier;
this.controller = controller;
this.keyRelationship = keyRelationship;
this.authentication = authentication;
Expand Down
2 changes: 2 additions & 0 deletions packages/did/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
export * from './did';
export * as helpers from './did/helpers';

export * as keys from './keys';

export * from './hasher';
37 changes: 37 additions & 0 deletions packages/did/src/keys/backup.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { generateMnemonic } from '@zcloak/crypto';
import { Keyring } from '@zcloak/keyring';

import { createEcdsaFromMnemonic } from '../did/helpers';
import { backup, getEcdsaIdentifierPair } from './backup';
import { DEFAULT_DID_KEYS_JSON_VERSION } from './defaults';

describe('Backup did', (): void => {
const keyring = new Keyring();

it('get ecdsa identifier pair', () => {
const mnemonic = generateMnemonic(12);
const did = createEcdsaFromMnemonic(mnemonic, keyring);

expect(getEcdsaIdentifierPair(keyring, did)?.publicKey).toEqual(
keyring.createFromMnemonic(mnemonic, undefined, 'ecdsa').publicKey
);
});

it('backup did', () => {
const mnemonic = generateMnemonic(12);
const did = createEcdsaFromMnemonic(mnemonic, keyring);

expect(backup(keyring, did, '1234')).toMatchObject({
didUrl: did.id,
version: DEFAULT_DID_KEYS_JSON_VERSION,
authentication: Array.from(did.authentication ?? []),
assertionMethod: Array.from(did.assertionMethod ?? []),
keyAgreement: Array.from(did.keyAgreement ?? []),
capabilityInvocation: Array.from(did.capabilityInvocation ?? []),
capabilityDelegation: Array.from(did.capabilityDelegation ?? [])
});
});
});
43 changes: 43 additions & 0 deletions packages/did/src/keys/backup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { KeyringPair } from '@zcloak/keyring/types';
import type { Did } from '../did';
import type { DidKeys$Json } from './types';

import { assert } from '@polkadot/util';

import { ethereumEncode } from '@zcloak/crypto';
import { Keyring } from '@zcloak/keyring';

import { DEFAULT_DID_KEYS_JSON_VERSION } from './defaults';

export function getEcdsaIdentifierPair(keyring: Keyring, did: Did): KeyringPair | undefined {
const identifierPair = keyring
.getPairs()
.find((pair) => ethereumEncode(pair.publicKey) === did.identifier);

return identifierPair;
}

export function backup(keyring: Keyring, did: Did, password: string): DidKeys$Json {
const identifierPair = getEcdsaIdentifierPair(keyring, did);

assert(identifierPair, 'no identifier pair found');

return {
didUrl: did.id,
version: DEFAULT_DID_KEYS_JSON_VERSION,
identifierKey: identifierPair.toJson(password),
keys: Array.from(did.keyRelationship.values()).map(({ publicKey }) => {
const pair = did.getPair(publicKey);

return pair.toJson(password);
}),
authentication: Array.from(did.authentication ?? []),
assertionMethod: Array.from(did.assertionMethod ?? []),
keyAgreement: Array.from(did.keyAgreement ?? []),
capabilityInvocation: Array.from(did.capabilityInvocation ?? []),
capabilityDelegation: Array.from(did.capabilityDelegation ?? [])
};
}
6 changes: 6 additions & 0 deletions packages/did/src/keys/defaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { DidKeys$JsonVersion } from './types';

export const DEFAULT_DID_KEYS_JSON_VERSION: DidKeys$JsonVersion = '1';
5 changes: 5 additions & 0 deletions packages/did/src/keys/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

export * from './backup';
export * from './restore';
22 changes: 22 additions & 0 deletions packages/did/src/keys/restore.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { generateMnemonic } from '@zcloak/crypto';
import { Keyring } from '@zcloak/keyring';

import { createEcdsaFromMnemonic } from '../did/helpers';
import { backup } from './backup';
import { restore } from './restore';

describe('Restore did', (): void => {
const keyring = new Keyring();

it('backup did and restore', () => {
const mnemonic = generateMnemonic(12);
const did = createEcdsaFromMnemonic(mnemonic, keyring);

const json = backup(keyring, did, '1234');

expect(restore(keyring, json, '1234')).toMatchObject(did);
});
});
47 changes: 47 additions & 0 deletions packages/did/src/keys/restore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { DidUrl } from '@zcloak/did-resolver/types';
import type { Keyring } from '@zcloak/keyring';
import type { DidKeys$Json } from './types';

import { Did } from '../did';
import { create } from '../did/helpers';
import { IDidDetails, KeyRelationship } from '../types';

export function restore(keyring: Keyring, json: DidKeys$Json, password: string): Did {
const keyRelationship = new Map<DidUrl, KeyRelationship>();

json.keys.forEach((key, index) => {
const pair = keyring.addFromJson(key);

pair.unlock(password);

const id: DidUrl = `${json.didUrl}#key-${index}`;
const controller: DidUrl[] = [`${json.didUrl}`];
const publicKey = pair.publicKey;

keyRelationship.set(id, {
id,
controller,
publicKey
});
});
const pair = keyring.addFromJson(json.identifierKey);

pair.unlock(password);

const details: IDidDetails = {
id: json.didUrl,
controller: new Set([json.didUrl]),
keyRelationship,
authentication: new Set(json.authentication),
assertionMethod: new Set(json.assertionMethod),
keyAgreement: new Set(json.keyAgreement),
capabilityInvocation: new Set(json.capabilityInvocation),
capabilityDelegation: new Set(json.capabilityDelegation),
service: new Map()
};

return create(details, keyring);
}
19 changes: 19 additions & 0 deletions packages/did/src/keys/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { DidUrl } from '@zcloak/did-resolver/types';
import type { KeyringPair$Json } from '@zcloak/keyring/types';

export type DidKeys$JsonVersion = '1';

export interface DidKeys$Json {
didUrl: DidUrl;
version: DidKeys$JsonVersion;
identifierKey: KeyringPair$Json;
keys: KeyringPair$Json[];
authentication: DidUrl[];
assertionMethod: DidUrl[];
keyAgreement: DidUrl[];
capabilityInvocation: DidUrl[];
capabilityDelegation: DidUrl[];
}
14 changes: 5 additions & 9 deletions tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
{
"extends": "./tsconfig.base.json",
"exclude": [
"build/**/*",
"**/build/**/*"
],
"compilerOptions": {
"baseUrl": "./packages",
"composite": false
},
"include": [
"packages/**/src/**/*",
"packages/**/scripts/**/*",
"packages/**/test/**/*"
],
"exclude": [
"**/node_modules/**/*"
]
}
}

0 comments on commit bfb9914

Please sign in to comment.