diff --git a/agent-swagger.json b/agent-swagger.json index 996110fdb3c2adc20c832e1663952a77a883fad6..c716c43adc674cf74c7ceda455b0078c4a9815fe 100644 --- a/agent-swagger.json +++ b/agent-swagger.json @@ -1089,6 +1089,34 @@ } } } + }, + "/api/v1/ocm/request-sender-email-vc": { + "post": { + "operationId": "RestController_requestSenderEmailVC", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestSenderEmailVcDto" + } + } + } + }, + "responses": { + "201": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RequestSenderEmailVcResponseDto" + } + } + } + } + } + } } }, "info": { @@ -1945,6 +1973,36 @@ "method", "tags" ] + }, + "RequestSenderEmailVcDto": { + "type": "object", + "properties": { + "email": { + "type": "string" + } + }, + "required": [ + "email" + ] + }, + "RequestSenderEmailVcResponseDto": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "did": { + "type": "string" + }, + "vc": { + "type": "object" + } + }, + "required": [ + "email", + "did", + "vc" + ] } } } diff --git a/libs/askar/src/agent.utils.ts b/libs/askar/src/agent.utils.ts index 1f49aa05c58b46e25d79e703d50f9c67c776104f..5f88429219c86d2930abcf93834db5854a32a38a 100644 --- a/libs/askar/src/agent.utils.ts +++ b/libs/askar/src/agent.utils.ts @@ -65,6 +65,7 @@ import { SvdxDidResolver, SvdxModule, DefaultIpfsClient, + SvdxRecordsApi, } from "@vereign/credo-did-svdx"; import { SubjectInboundTransport } from "./askar/transports/agent.subject.inbound.transport"; @@ -204,9 +205,45 @@ export const generateDidWeb = async ({ console.log(JSON.stringify(didDocumentInstance.toJSON(), null, 2)); }; -export const generateRandomDidSvdx = async (agent: Agent) => { - const seed = crypto.randomBytes(46).toString("hex"); - return generateDidSvdx({ agent, seed }); +export const generateDidSvdxForEmail = async (agent: Agent, email: string) => { + const activeKeySeed = crypto.randomBytes(46).toString("hex"); + const nextKeySeed = crypto.randomBytes(46).toString("hex"); + const activeKey = await generateKey({ seed: activeKeySeed, agent }); + const nextKey = await generateKey({ seed: nextKeySeed, agent }); + + const WalletKeyPair = createWalletKeyPairClass(agent.context.wallet); + + const keyPair = new WalletKeyPair({ + id: `key-1`, + controller: `did:svdx:${activeKey.fingerprint}`, + key: activeKey, + wallet: agent.context.wallet, + }); + + const didResult = await agent.dids.create({ + method: "svdx", + options: { + inceptionKey: activeKey, + nextKey: nextKey, + signer: { signer: () => keyPair.signer() }, + }, + }); + + if (!didResult.didState.didDocument || !didResult.didState.did) { + throw new Error("Could not create did svdx"); + } + + const svdxApi: SvdxRecordsApi = agent.modules["svdx"]; + await svdxApi.save({ + email: email, + did: didResult.didState.did, + activeKey: activeKey.publicKeyBase58, + activeKeySeed: activeKeySeed, + nextKey: nextKey.publicKeyBase58, + nextKeySeed: nextKeySeed, + }); + + return didResult; }; export const generateDidSvdx = async ({ diff --git a/libs/askar/src/askar/services/agent.ocm.service.ts b/libs/askar/src/askar/services/agent.ocm.service.ts index 5ef2a31efd2bb629ebae4bfa3313ddd21542db87..6a42a224420430a2a18d6e109316d9bfd7f81d8c 100644 --- a/libs/askar/src/askar/services/agent.ocm.service.ts +++ b/libs/askar/src/askar/services/agent.ocm.service.ts @@ -1,7 +1,11 @@ import { Injectable, Logger } from "@nestjs/common"; -import { EntityNotFoundError, RequestSenderEmailVcDto } from "@ocm-engine/dtos"; +import { + EntityNotFoundError, + RequestSenderEmailVcDto, + RequestSenderEmailVcResponseDto, +} from "@ocm-engine/dtos"; import { CatalogClient } from "../clients/catalog.client"; -import { generateRandomDidSvdx } from "../../agent.utils"; +import { generateDidSvdxForEmail } from "../../agent.utils"; import { AskarService } from "./askar.service"; import { IConfCatalog } from "@ocm-engine/config"; import { ConfigService } from "@nestjs/config"; @@ -28,11 +32,7 @@ export class AgentOcmService { requestSenderEmailVC = async ( dto: RequestSenderEmailVcDto, - ): Promise<{ - email: string; - did: string; - vc: object; - }> => { + ): Promise<RequestSenderEmailVcResponseDto> => { this.ensureActivated(); this.logger.debug(`requestSenderEmailVC`, dto.email); @@ -55,7 +55,10 @@ export class AgentOcmService { }; } - const newDidSvdx = await generateRandomDidSvdx(this.askar.agent); + const newDidSvdx = await generateDidSvdxForEmail( + this.askar.agent, + dto.email, + ); if (!newDidSvdx.didState.did) { throw new Error("Svdx did generation failed"); diff --git a/libs/dtos/src/dtos/responses/request.sender.email.vc.response.dto.ts b/libs/dtos/src/dtos/responses/request.sender.email.vc.response.dto.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd1658e2a632743f47f8431b410fef0cc246f4fe --- /dev/null +++ b/libs/dtos/src/dtos/responses/request.sender.email.vc.response.dto.ts @@ -0,0 +1,5 @@ +export class RequestSenderEmailVcResponseDto { + public email: string; + public did: string; + public vc: object; +} diff --git a/libs/dtos/src/index.ts b/libs/dtos/src/index.ts index cedb6f7f6eb8a7f42635c3e456dde263f3ae1804..78e69c6a40663c02b00ecadd5519b37fb5024998 100644 --- a/libs/dtos/src/index.ts +++ b/libs/dtos/src/index.ts @@ -43,6 +43,7 @@ export * from "./dtos/responses/request.proof.response.dto"; export * from "./dtos/responses/credential.offer.response.dto"; export * from "./dtos/responses/create.invitation.response.dto"; export * from "./dtos/responses/gateway.accepted.response.dto"; +export * from "./dtos/responses/request.sender.email.vc.response.dto"; export * from "./errors/ocm.error"; export * from "./errors/entity.not.found.error"; diff --git a/package.json b/package.json index 3034c99d2a55ce37114cddf8fdd58688ccf7304e..81488157f1e4d581f936fb176ffae200b80ff8df 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@nestjs/swagger": "^6.3.0", "@nestjs/websockets": "^9.4.2", "@swc/helpers": "~0.5.2", - "@vereign/credo-did-svdx": "0.1.0", + "@vereign/credo-did-svdx": "^0.1.1", "@vereign/did-svdx": "^0.1.1", "antd": "^5.10.1", "async-retry": "^1.3.3", diff --git a/yarn.lock b/yarn.lock index 5c4ccfcaa5018587a6dd09d5deeef3eb787b8919..cbc8e9a9c071415982bc99f46fb6a6530b563433 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4341,10 +4341,10 @@ expo-modules-autolinking "^0.0.3" invariant "^2.2.4" -"@vereign/credo-did-svdx@0.1.0": - version "0.1.0" - resolved "https://code.vereign.com/api/v4/projects/740/packages/npm/@vereign/credo-did-svdx/-/@vereign/credo-did-svdx-0.1.0.tgz#6f0b724cd05b59b482f2725229233b23bb85bdf8" - integrity sha1-bwtyTNBbWbSC8nJSKSM7I7uFvfg= +"@vereign/credo-did-svdx@^0.1.1": + version "0.1.1" + resolved "https://code.vereign.com/api/v4/projects/740/packages/npm/@vereign/credo-did-svdx/-/@vereign/credo-did-svdx-0.1.1.tgz#d9c415baa99e93ab1f86a64365388c673cbe5b9d" + integrity sha1-2cQVuqmek6sfhqZDZTiMZzy+W50= dependencies: axios "^1.7.2" tslib "^2.3.0"