Skip to content

Commit

Permalink
feat: implementing Startable and propogating stop()
Browse files Browse the repository at this point in the history
Signed-off-by: Curtish <ch@curtish.me>
  • Loading branch information
curtis-h committed Oct 22, 2024
1 parent e6d0008 commit aaa05f7
Show file tree
Hide file tree
Showing 14 changed files with 426 additions and 156 deletions.
9 changes: 8 additions & 1 deletion src/domain/buildingBlocks/Pluto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,18 @@ export namespace Pluto {
* preferred underlying storage technology, most appropriate for your use case.
*/
export interface Pluto {
// TODO extend Startable.Controller (changes the interface)

/**
* Pluto initialise function
* Handle startup.
*/
start(): Promise<void>;

/**
* Handle teardown.
*/
stop?(): Promise<void>;

/**
* create a Backup object from the stored data
*/
Expand Down
19 changes: 9 additions & 10 deletions src/domain/buildingBlocks/Pollux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export type CredentialOfferJWTBasePayload = {
options: {
challenge: string;
domain: string;
}
}
};
};

export type CredentialOfferPayloads = {
[CredentialType.AnonCreds]: Anoncreds.CredentialOfferType;
Expand Down Expand Up @@ -48,9 +48,8 @@ export type ProcessedCredentialOfferPayloads = {
* handle Credential related tasks
*/
export interface Pollux {

revealCredentialFields: (credential: Credential, fields: string[], linkSecret: string) => Promise<{
[name: string]: any
[name: string]: any;
}>;

isCredentialRevoked: (credential: Credential) => Promise<boolean>;
Expand All @@ -71,12 +70,12 @@ export interface Pollux {
presentationDefinition: PresentationDefinitionRequest<CredentialType.JWT>,
credential: Credential,
privateKey: PrivateKey
): Promise<PresentationSubmission<CredentialType.JWT>>
): Promise<PresentationSubmission<CredentialType.JWT>>;
createPresentationSubmission(
presentationDefinition: PresentationDefinitionRequest<CredentialType.AnonCreds>,
credential: Credential,
privateKey: LinkSecret
): Promise<PresentationSubmission<CredentialType.AnonCreds>>
): Promise<PresentationSubmission<CredentialType.AnonCreds>>;

/**
* Process a PresentationSubmission, resolve the issuer did and verify the credential and the holder signature
Expand All @@ -88,15 +87,15 @@ export interface Pollux {
verifyPresentationSubmission(
presentationSubmission: PresentationSubmission<CredentialType.JWT>,
options?: Pollux.verifyPresentationSubmission.options.JWT
): Promise<boolean>
): Promise<boolean>;
verifyPresentationSubmission(
presentationSubmission: PresentationSubmission<CredentialType.AnonCreds>,
options?: Pollux.verifyPresentationSubmission.options.Anoncreds
): Promise<boolean>
): Promise<boolean>;
verifyPresentationSubmission(
presentationSubmission: PresentationSubmission,
options?: Pollux.verifyPresentationSubmission.options.JWT | Pollux.verifyPresentationSubmission.options.Anoncreds
): Promise<boolean>
): Promise<boolean>;

/**
* Creates a PresentationDefinitionRequest object for oob Verifications
Expand All @@ -108,7 +107,7 @@ export interface Pollux {
type: T,
claims: PresentationClaims<T>,
options: PresentationOptions
): Promise<PresentationDefinitionRequest<T>>
): Promise<PresentationDefinitionRequest<T>>;



Expand Down
41 changes: 17 additions & 24 deletions src/edge-agent/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,8 @@ import { SignWithDID } from "./didFunctions/Sign";
import { CreatePrismDID } from "./didFunctions/CreatePrismDID";
import { FetchApi } from "./helpers/FetchApi";
import { Task } from "../utils/tasks";

enum AgentState {
STOPPED = "stopped",
STARTING = "starting",
RUNNING = "running",
STOPPING = "stopping",
}
import { Startable } from "../utils/startable";
import { notNil } from "../utils";

/**
* Edge agent implementation
Expand All @@ -22,14 +17,14 @@ enum AgentState {
* @class Agent
* @typedef {Agent}
*/
export default class Agent {
export default class Agent implements Startable.Controller {
/**
* Agent state
*
* @public
* @type {AgentState}
* @type {Startable.State}
*/
public state: AgentState = AgentState.STOPPED;
public state = Startable.State.STOPPED;
public backup: AgentBackup;
public readonly pollux: Pollux;

Expand Down Expand Up @@ -86,30 +81,28 @@ export default class Agent {
/**
* Asyncronously start the agent
*
* @async
* @returns {Promise<AgentState>}
*/
async start(): Promise<AgentState> {
if (this.state === AgentState.STOPPED) {
this.state = AgentState.STARTING;
start(): Promise<Startable.State> {
return Startable.start(this, async () => {
await this.pluto.start();
await this.pollux.start();
}

return this.state;
});
}

/**
* Asyncronously stop the agent and any side task that is running
*
* @async
* @returns {Promise<void>}
* @returns {Promise<Startable.State>}
*/
async stop(): Promise<void> {
if (this.state !== AgentState.RUNNING) {
return;
}
this.state = AgentState.STOPPED;
stop(): Promise<Startable.State> {
return Startable.stop(this, async () => {
await this.pollux.stop();

if (notNil(this.pluto.stop)) {
await this.pluto.stop();
}
});
}

/**
Expand Down
110 changes: 45 additions & 65 deletions src/edge-agent/didcomm/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,8 @@ import { FetchApi } from "../helpers/FetchApi";
import { ParsePrismInvitation } from "./ParsePrismInvitation";
import { ParseInvitation } from "./ParseInvitation";
import { HandleOOBInvitation } from "./HandleOOBInvitation";

enum AgentState {
STOPPED = "stopped",
STARTING = "starting",
RUNNING = "running",
STOPPING = "stopping",
}
import { Startable } from "../../utils/startable";
import { notNil } from "../../utils";

/**
* Edge agent implementation
Expand All @@ -52,14 +47,8 @@ enum AgentState {
* @class Agent
* @typedef {Agent}
*/
export default class DIDCommAgent {
/**
* Agent state
*
* @public
* @type {AgentState}
*/
public state: AgentState = AgentState.STOPPED;
export default class DIDCommAgent implements Startable.Controller {
public state = Startable.State.STOPPED;
public backup: AgentBackup;
public readonly pollux: Pollux;

Expand Down Expand Up @@ -148,64 +137,55 @@ export default class DIDCommAgent {
return agent;
}

start(): Promise<Startable.State> {
return Startable.start(this, async () => {
try {
this.state = Startable.State.STARTING;
await this.pluto.start();
await this.pollux.start();
await this.connectionManager.startMediator();
}
catch (e) {
if (e instanceof Domain.AgentError.NoMediatorAvailableError) {
const hostDID = await this.createNewPeerDID([], false);
await this.connectionManager.registerMediator(hostDID);
}
else {
throw e;
}
}

/**
* Asyncronously start the agent
*
* @async
* @returns {Promise<AgentState>}
*/
async start(): Promise<AgentState> {
if (this.state !== AgentState.STOPPED) {
return this.state;
}

try {
this.state = AgentState.STARTING;
await this.pluto.start();
await this.pollux.start();
await this.connectionManager.startMediator();
} catch (e) {
if (e instanceof Domain.AgentError.NoMediatorAvailableError) {
const hostDID = await this.createNewPeerDID([], false);

await this.connectionManager.registerMediator(hostDID);

} else throw e;
}

if (this.connectionManager.mediationHandler.mediator !== undefined) {
await this.connectionManager.startFetchingMessages(5);
this.state = AgentState.RUNNING;
} else {
throw new Domain.AgentError.MediationRequestFailedError("Mediation failed");
}

const storedLinkSecret = await this.pluto.getLinkSecret();
if (storedLinkSecret == null) {
const secret = this.pollux.anoncreds.createLinksecret();
const linkSecret = new Domain.LinkSecret(secret);
await this.pluto.storeLinkSecret(linkSecret);
}
if (this.connectionManager.mediationHandler.mediator !== undefined) {
await this.connectionManager.startFetchingMessages(5);
}
else {
throw new Domain.AgentError.MediationRequestFailedError("Mediation failed");
}

return this.state;
const storedLinkSecret = await this.pluto.getLinkSecret();
if (storedLinkSecret == null) {
const secret = this.pollux.anoncreds.createLinksecret();
const linkSecret = new Domain.LinkSecret(secret);
await this.pluto.storeLinkSecret(linkSecret);
}
});
}

/**
* Asyncronously stop the agent and any side task that is running
* Asyncronously stop the agent and dependencies
*
* @async
* @returns {Promise<void>}
*/
async stop(): Promise<void> {
if (this.state !== AgentState.RUNNING) {
return;
}
this.state = AgentState.STOPPING;
await this.connectionManager.stopAllEvents();
await this.connectionManager.stopFetchingMessages();
// await this.agent.stop();
this.state = AgentState.STOPPED;
stop(): Promise<Startable.State> {
return Startable.stop(this, async () => {
await this.connectionManager.stopAllEvents();
await this.connectionManager.stopFetchingMessages();
await this.pollux.stop();

if (notNil(this.pluto.stop)) {
await this.pluto.stop();
}
});
}

/**
Expand Down
36 changes: 16 additions & 20 deletions src/edge-agent/oidc/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { Task } from "../../utils/tasks";
import * as DIDfns from "../didFunctions";
import * as Tasks from "./tasks";
import * as Errors from "./errors";
import { JsonObj, expect } from "../../utils";
import { JsonObj, expect, notNil } from "../../utils";
import { Startable } from "../../utils/startable";

/**
* https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html
Expand All @@ -24,20 +25,12 @@ class Connection {
public readonly issuerMeta: OIDC.IssuerMetadata,
public readonly scopes: string[],
public readonly tokenResponse: TokenResponse,
) { }
) {}
}

// TODO make startable interface
enum AgentState {
STOPPED = "stopped",
STARTING = "starting",
RUNNING = "running",
STOPPING = "stopping",
}

export class OIDCAgent {
export class OIDCAgent implements Startable.Controller {
private connections: Connection[] = [];
public state = AgentState.STOPPED;
public state = Startable.State.STOPPED;
public readonly pollux: Pollux;

constructor(
Expand Down Expand Up @@ -81,18 +74,21 @@ export class OIDCAgent {
return agent;
}

async start() {
if (this.state === AgentState.STOPPED) {
this.state = AgentState.STARTING;
start(): Promise<Startable.State> {
return Startable.start(this, async () => {
await this.pluto.start();
await this.pollux.start();
this.state = AgentState.RUNNING;
}
return this.state;
});
}

async stop(): Promise<void> {
this.state = AgentState.STOPPED
async stop(): Promise<Startable.State> {
return Startable.stop(this, async () => {
await this.pollux.stop();

if (notNil(this.pluto.stop)) {
await this.pluto.stop();
}
});
}

private runTask<T>(task: Task<T>): Promise<T> {
Expand Down
Loading

0 comments on commit aaa05f7

Please sign in to comment.