Skip to content

Commit

Permalink
fix: initiatePresentationRequest on the edge agent and pollux improve…
Browse files Browse the repository at this point in the history
…ments.
  • Loading branch information
elribonazo committed Apr 25, 2024
1 parent 23e05ab commit 9493921
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 46 deletions.
49 changes: 48 additions & 1 deletion src/domain/buildingBlocks/Pollux.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,49 @@
import { AnonCredsCredential } from "../../pollux/models/AnonCredsVerifiableCredential";
import { PresentationRequest } from "../../pollux/models/PresentationRequest";
import { JWTCredential } from "../../pollux/models/JWTVerifiableCredential";
import { CredentialType, DID, LinkSecret, Message, PrivateKey } from "../models";
import { CredentialType, DID, LinkSecret, Message, PresentationDefinitionRequest, PrivateKey, PublicKey } from "../models";
import { Anoncreds } from "../models/Anoncreds";
import { Credential, CredentialRequestOptions } from "../models/Credential";
import { ProofTypes } from "../../prism-agent/protocols/types";

type CredentialRequestTuple<
T1 = Anoncreds.CredentialRequest,
T2 = Anoncreds.CredentialRequestMeta
> = [T1, T2];


export type PresentationJWTOptions = {
jwtAlg?: string[],
jwtVcAlg?: string[],
jwtVpAlg?: string[]
}

export class PresentationOptions {
public name: string;
public purpose: string;
public challenge: string;
public domain: string;
public jwt?: PresentationJWTOptions

constructor(
options: {
name?: string,
purpose?: string,
challenge: string,
domain: string,
jwt?: PresentationJWTOptions
}
) {

this.name = options.name ?? "Presentation";
this.purpose = options.purpose ?? "Verifying Credentials";
this.challenge = options.challenge;
this.domain = options.domain;
this.jwt = options.jwt;

}
}

/**
* Pollux
* handle Credential related tasks
Expand All @@ -29,7 +63,20 @@ export interface Pollux {
): Promise<CredentialRequestTuple>;
extractCredentialFormatFromMessage(message: Message): CredentialType;

/**
* Creates a PresentationDefinitionRequest object for oob Verifications
* @param {CredentialType} type
* @param {ProofTypes} proofs
* @param {PresentationOptions} options
*/
createPresentationDefinitionRequest(
type: CredentialType,
proofs: ProofTypes[],
options: PresentationOptions
): Promise<PresentationDefinitionRequest>


verifyPresentationSubmissionJWT(submission: Uint8Array, publicKey: PublicKey): Promise<boolean>
/**
* Process a PresentationRequest with Credential to create a Presentation.
*
Expand Down
22 changes: 19 additions & 3 deletions src/domain/models/MessageAttachment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,33 @@ export class AttachmentDescriptor {
public readonly lastModTime?: string,
public readonly byteCount?: number,
public readonly description?: string
) {}
) { }

static build<T>(
payload: T,
id: string = uuid(),
mediaType = "application/json"
mediaType = "application/json",
filename?: Array<string>,
format?: string,
lastModTime?: string,
byteCount?: number,
description?: string

): AttachmentDescriptor {
const encoded = base64.baseEncode(Buffer.from(JSON.stringify(payload)));
const attachment: AttachmentBase64 = {
base64: encoded,
};
return new AttachmentDescriptor(attachment, mediaType, id);

return new AttachmentDescriptor(
attachment,
mediaType,
id,
filename,
format,
lastModTime,
byteCount,
description
);
}
}
62 changes: 60 additions & 2 deletions src/domain/models/VerifiableCredential.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
export enum CredentialType {
JWT = "jwt",
JWT = "prism/jwt",
W3C = "w3c",
AnonCreds = "AnonCreds",
Unknown = "Unknown",
ANONCREDS_OFFER = "anoncreds/credential-offer@v1.0",
ANONCREDS_REQUEST = "anoncreds/credential-request@v1.0",
ANONCREDS_ISSUE = "anoncreds/credential@v1.0",
ANONCREDS_PROOF_REQUEST = "anoncreds/proof-request@v1.0",
PRESENTATION_EXCHANGE_DEFINITIONS = "dif/presentation-exchange/definitions@v1.0",
PRESENTATION_EXCHANGE_SUBMISSION = "dif/presentation-exchange/submission@v1.0",
Unknown = "Unknown"
}

export interface CredentialSubject {
Expand All @@ -13,3 +19,55 @@ export interface VerifiableCredentialTypeContainer {
id: string;
type: string;
}


export type InputFieldFilter = {
type: string,
pattern: string
}

export type InputField = {
path: string[],
id?: string,
purpose?: string,
name?: string,
filter?: InputFieldFilter,
optional?: boolean
}

export enum InputLimitDisclosure {
REQUIRED = "required",
PREFERRED = "preferred"
}

export type InputConstraints = {
fields: InputField[],
limitDisclosure: InputLimitDisclosure
}

export type InputDescriptor = {
id: string,
constraints: InputConstraints,
name?: string,
purpose?: string,
format?: DefinitionFormat,
}

export type JWT_FORMAT = {
jwt_vc?: {
alg: string[]
},
jwt_vp?: {
alg: string[]
}
}

export type DefinitionFormat = {
jwt?: JWT_FORMAT
};

export type PresentationDefinitionRequest = {
id: string,
inputDescriptors: InputDescriptor[],
format: DefinitionFormat
}
8 changes: 5 additions & 3 deletions src/domain/models/errors/Pollux.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

export class InvalidCredentialError extends Error {}
export class InvalidJWTString extends Error {}
export class InvalidPresentationProofArgs extends Error {}
export class InvalidCredentialError extends Error { }
export class InvalidJWTString extends Error { }
export class InvalidPresentationProofArgs extends Error { }
export class CredsentialTypeNotSupported extends Error { }
export class InvalidJWTPresentationDefinitionError extends Error { }
99 changes: 94 additions & 5 deletions src/pollux/Pollux.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { uuid } from "@stablelib/uuid";

import { Castor } from "../domain/buildingBlocks/Castor";
import { Pollux as IPollux } from "../domain/buildingBlocks/Pollux";
import { Pollux as IPollux, PresentationOptions } from "../domain/buildingBlocks/Pollux";
import { InvalidJWTString } from "../domain/models/errors/Pollux";
import { base64url, base64 } from "multiformats/bases/base64";
import { AnoncredsLoader } from "./AnoncredsLoader";
Expand All @@ -12,6 +14,14 @@ import {
Api,
PolluxError,
Credential,
PresentationDefinitionRequest,
PublicKey,
InputConstraints,
InputField,
InputLimitDisclosure,
InputDescriptor,
DefinitionFormat,
JWT_FORMAT,
} from "../domain";
import { AnonCredsCredential } from "./models/AnonCredsVerifiableCredential";

Expand All @@ -20,6 +30,7 @@ import { JWT } from "../apollo/utils/jwt/JWT";
import { Anoncreds } from "../domain/models/Anoncreds";
import { ApiImpl } from "../prism-agent/helpers/ApiImpl";
import { PresentationRequest } from "./models/PresentationRequest";
import { ProofTypes } from "../prism-agent/protocols/types";

/**
* Implementation of Pollux
Expand All @@ -36,6 +47,83 @@ export default class Pollux implements IPollux {
private api: Api = new ApiImpl()
) { }



async createPresentationDefinitionRequest(
type: CredentialType,
proofs: ProofTypes[],
options: PresentationOptions
): Promise<PresentationDefinitionRequest> {
if (type !== CredentialType.JWT) {
throw new PolluxError.CredsentialTypeNotSupported()
}

const jwtOptions = options.jwt;
if (!jwtOptions) {
//TODO: improve erorr handling
throw new Error("Required field options jwt is undefined")
}

if (!jwtOptions.jwtAlg &&
!jwtOptions.jwtVcAlg &&
!jwtOptions.jwtVpAlg) {
throw new PolluxError.InvalidJWTPresentationDefinitionError("Presentation options didn't include jwtAlg, jwtVcAlg or jwtVpAlg, one of them is required.")
}

const paths =
proofs.reduce<string[]>((all, proof) => {
return [
...all,
...(proof.requiredFields ?? []),
...(proof.trustIssuers ?? [])
]
}, []);

const constaints: InputConstraints = {
fields: paths.map((path) => {
const inputField: InputField = {
path: [path],
id: uuid(),
optional: false
}
return inputField
}),
limitDisclosure: InputLimitDisclosure.REQUIRED
};

const inputDescriptor: InputDescriptor = {
id: uuid(),
name: options.name,
purpose: options.purpose,
constraints: constaints
}

const format: JWT_FORMAT = {
jwt_vc: {
alg: jwtOptions.jwtVcAlg ?? []
},
jwt_vp: {
alg: jwtOptions.jwtVpAlg ?? []
}
}

const presentationDefinitionRequest: PresentationDefinitionRequest = {
id: uuid(),
inputDescriptors: [
inputDescriptor
],
format: {
jwt: format
}
}

return presentationDefinitionRequest
}

verifyPresentationSubmissionJWT(submission: Uint8Array, publicKey: PublicKey): Promise<boolean> {
throw new Error("Method not implemented.");
}

async start() {
this._anoncreds = await AnoncredsLoader.getInstance();
}
Expand All @@ -57,14 +145,15 @@ export default class Pollux implements IPollux {
}

if (
attachment.format === "anoncreds/proof-request@v1.0" ||
attachment.format === "anoncreds/credential-offer@v1.0" ||
attachment.format === "anoncreds/credential@v1.0"
attachment.format === CredentialType.ANONCREDS_PROOF_REQUEST ||
attachment.format === CredentialType.ANONCREDS_OFFER ||
attachment.format === CredentialType.ANONCREDS_ISSUE ||
attachment.format === CredentialType.ANONCREDS_REQUEST
) {
return CredentialType.AnonCreds;
}

if (attachment.format === "prism/jwt") {
if (attachment.format === CredentialType.JWT) {
return CredentialType.JWT;
}

Expand Down

0 comments on commit 9493921

Please sign in to comment.