Skip to content

Commit

Permalink
feat(agent): Implementing DIDComm V2 Protocols + Demo showcasing (hyp…
Browse files Browse the repository at this point in the history
…erledger-identus#36)

Co-authored-by: Curtish <[email protected]>
  • Loading branch information
elribonazo and curtis-h authored Mar 28, 2023
1 parent 3a011cb commit 515d835
Show file tree
Hide file tree
Showing 56 changed files with 3,264 additions and 1,364 deletions.
40 changes: 40 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2021,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"ignorePatterns": ["castor/parser", "castor/protos", "webpack", "scripts"],
"plugins": ["@typescript-eslint", "react"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
],
"rules": {
"comma-dangle": 0,
"no-unexpected-multiline": "warn",
"prefer-const": "warn",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": ["warn"]
},
"settings": {
"react": {
"version": "detect"
}
},
"env": {
"browser": true,
"node": true,
"jasmine": true,
"jest": true,
"es2021": true
}
}
32 changes: 0 additions & 32 deletions .eslintrc.json

This file was deleted.

1 change: 0 additions & 1 deletion apollo/models/OctetKeyPair.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { curve } from "elliptic";
import { KeyPair } from "../../domain";

interface PublicJson {
Expand Down
95 changes: 95 additions & 0 deletions apollo/utils/jwt/JWT.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as didJWT from "did-jwt";

import Castor from "../../../domain/buildingBlocks/Castor";
import { DIDResolutionResult } from "did-resolver";
import {
AlsoKnownAs,
Controller,
Services,
VerificationMethods,
DID,
} from "../../../domain";

export class JWT {
private castor: Castor;

constructor(castor: Castor) {
this.castor = castor;
}

private async resolve(did: string): Promise<DIDResolutionResult> {
const resolved = await this.castor.resolveDID(did);
const alsoKnownAs = resolved.coreProperties.find(
(prop): prop is AlsoKnownAs => prop instanceof AlsoKnownAs
);
const controller = resolved.coreProperties.find(
(prop): prop is Controller => prop instanceof Controller
);
const verificationMethods = resolved.coreProperties.find(
(prop): prop is VerificationMethods => prop instanceof VerificationMethods
);
const service = resolved.coreProperties.find(
(prop): prop is Services => prop instanceof Services
);

return {
didResolutionMetadata: { contentType: "application/did+ld+json" },
didDocumentMetadata: {},
didDocument: {
id: resolved.id.toString(),
alsoKnownAs: alsoKnownAs && alsoKnownAs.values,
controller:
controller && controller.values
? controller.values.map((v) => v.toString())
: [],
verificationMethod:
verificationMethods && verificationMethods.values
? verificationMethods.values.map((vm) => {
if (vm.publicKeyMultibase) {
return {
id: vm.id,
type: "EcdsaSecp256k1VerificationKey2019",
controller: vm.controller,
publicKeyMultibase: vm.publicKeyMultibase,
};
}
if (vm.publicKeyJwk) {
return {
id: vm.id,
type: "JsonWebKey2020",
controller: vm.controller,
publicKeyJwk: vm.publicKeyJwk,
};
}
throw new Error("Invalid KeyType");
})
: [],
service:
service && service.values
? service.values.map((service) => {
return {
id: service.id,
type: service.type[0],
serviceEndpoint: service.serviceEndpoint,
};
})
: [],
},
};
}

async sign(
issuer: DID,
privateKey: Uint8Array,
payload: Partial<didJWT.JWTPayload>
): Promise<string> {
//TODO: Better check if this method is called with PrismDID and not PeerDID or other
const signer = didJWT.ES256KSigner(privateKey);
const jwt = await didJWT.createJWT(
payload,
{ issuer: issuer.toString(), signer },
{ alg: "ES256K" }
);
return jwt;
}
}
14 changes: 10 additions & 4 deletions castor/Castor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import {
VerificationMethods as DIDDocumentVerificationMethods,
} from "../domain";
import * as base64 from "multiformats/bases/base64";
import * as base58 from "multiformats/bases/base58";

import { JWKHelper } from "../peer-did/helpers/JWKHelper";
import {
VerificationMaterialAgreement,
Expand Down Expand Up @@ -61,15 +63,19 @@ export default class Castor implements CastorInterface {
masterPublicKey: PublicKey,
services?: Service[] | undefined
): Promise<DID> {
const id = getUsageId(Usage.MASTER_KEY);
const publicKey = new PrismDIDPublicKey(
id,
getUsageId(Usage.MASTER_KEY),
Usage.MASTER_KEY,
masterPublicKey
);
const authenticateKey = new PrismDIDPublicKey(
getUsageId(Usage.AUTHENTICATION_KEY),
Usage.AUTHENTICATION_KEY,
masterPublicKey
);
const didCreationData =
new Protos.io.iohk.atala.prism.protos.CreateDIDOperation.DIDCreationData({
public_keys: [publicKey.toProto()],
public_keys: [authenticateKey.toProto(), publicKey.toProto()],
services: services?.map((service) => {
return new Protos.io.iohk.atala.prism.protos.Service({
service_endpoint: [service.serviceEndpoint.uri],
Expand Down Expand Up @@ -158,7 +164,7 @@ export default class Castor implements CastorInterface {
}

const publicKeyEncoded = Secp256k1PublicKey.secp256k1FromBytes(
Buffer.from(base64.base64.baseDecode(method.publicKeyMultibase))
Buffer.from(base58.base58btc.decode(method.publicKeyMultibase))
).getEncoded();

publicKey = {
Expand Down
20 changes: 10 additions & 10 deletions castor/did/prismDID/PrismDIDPublicKey.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Secp256k1PublicKey } from "../../../apollo/utils/Secp256k1PublicKey";
import Apollo from "../../../domain/buildingBlocks/Apollo";
import { CompressedPublicKey, Curve, PublicKey } from "../../../domain/models";
import { Curve, PublicKey } from "../../../domain/models";
import { CastorError } from "../../../domain/models/Errors";

import * as Protos from "../../protos/node_models";
Expand Down Expand Up @@ -45,21 +45,21 @@ export function getProtosUsage(
export function getUsageId(index: Usage): string {
switch (index) {
case Usage.MASTER_KEY:
return "master(index)";
return `master${index}`;
case Usage.ISSUING_KEY:
return "issuing(index)";
return `issuing${index}`;
case Usage.KEY_AGREEMENT_KEY:
return "agreement(index)";
return `agreement${index}`;
case Usage.AUTHENTICATION_KEY:
return "authentication(index)";
return `authentication${index}`;
case Usage.REVOCATION_KEY:
return "revocation(index)";
return `revocation${index}`;
case Usage.CAPABILITY_DELEGATION_KEY:
return "delegation(index)";
return `delegation${index}`;
case Usage.CAPABILITY_INVOCATION_KEY:
return "invocation(index)";
return `invocation${index}`;
default:
return "unknown(index)";
return `unknown${index}`;
}
}

Expand Down Expand Up @@ -142,7 +142,7 @@ export class PrismDIDPublicKey {
const key = Secp256k1PublicKey.secp256k1FromBytes(this.keyData.value);
const points = key.getCurvePoint();
const ecKeyData = new Protos.io.iohk.atala.prism.protos.ECKeyData({
curve: Curve.SECP256K1,
curve: Curve.SECP256K1.toLocaleLowerCase(),
x: points.x.bytes(),
y: points.y.bytes(),
});
Expand Down
3 changes: 2 additions & 1 deletion castor/resolver/LongFormPrismDIDResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
PrismDIDPublicKey,
} from "../../castor/did/prismDID/PrismDIDPublicKey";
import * as base64 from "multiformats/bases/base64";
import * as base58 from "multiformats/bases/base58";

export class LongFormPrismDIDResolver implements DIDResolver {
method = "prism";
Expand Down Expand Up @@ -127,7 +128,7 @@ export class LongFormPrismDIDResolver implements DIDResolver {
did.toString(),
publicKey.keyData.keyCurve.curve,
undefined,
base64.base64.baseEncode(publicKey.keyData.value)
base58.base58btc.encode(publicKey.keyData.value)
);
partialResult.set(didUrl.string(), method);
return partialResult;
Expand Down
4 changes: 2 additions & 2 deletions castor/resolver/PeerDIDResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export class PeerDIDResolver implements DIDResolver {
break;
case Numalgo2Prefix.service:
services.push(...this.decodeService(did, part.slice(1)));
break;
}
});
return new DIDDocument(did, [
Expand Down Expand Up @@ -220,7 +219,7 @@ export class PeerDIDResolver implements DIDResolver {
Array.isArray(serviceList) ? serviceList : [serviceList]
).map((service) => PeerDIDService.decode(service));

return services.map((service, offset) => {
const didcommServices = services.map((service, offset) => {
return new DIDDocumentService(
did.toString() + "#" + service.type + "-" + offset,
[service.type],
Expand All @@ -231,6 +230,7 @@ export class PeerDIDResolver implements DIDResolver {
)
);
});
return didcommServices;
} catch (e) {
throw new CastorError.NotPossibleToResolveDID();
}
Expand Down
Loading

0 comments on commit 515d835

Please sign in to comment.