From 6d031d779ad12124ed6ba5a3a3a4966e6f77d0f8 Mon Sep 17 00:00:00 2001
From: Alexey Lunin <alexey.lunin@vereign.com>
Date: Thu, 9 May 2024 07:30:44 +0300
Subject: [PATCH] OP#246 refactor DTOs so they are created by static method
 which force validation for required fields

---
 agent-swagger.json                            |   4 -
 .../src/app/app.controller.ts                 |  21 ++-
 .../src/app/app.controller.ts                 |   7 +-
 apps/proof-manager/src/app/app.controller.ts  |   7 +-
 .../services/agent-event-listener.service.ts  |  23 ++-
 .../askar/services/agent.anoncreds.service.ts | 100 ++++++------
 .../services/agent.basicMessages.service.ts   |  48 +++---
 .../services/agent.connections.service.ts     |  91 ++++++-----
 .../services/agent.credentials.service.ts     | 142 +++++++++---------
 .../src/askar/services/agent.dids.service.ts  |  17 ++-
 .../askar/services/agent.jsonld.service.ts    |  32 ++--
 .../src/askar/services/agent.oob.service.ts   |  85 +++++------
 .../askar/services/agent.proofs.service.ts    | 130 ++++++++--------
 libs/clients/src/frontend/agent_gen.ts        |   1 -
 .../dtos/src/dtos/generics/base.record.dto.ts |   8 +
 .../dtos/generics/connection.record.dto.ts    |  18 +++
 .../src/dtos/generics/creddef.record.dto.ts   |  11 ++
 .../generics/credential.formatData.dto.ts     |  12 ++
 .../dtos/generics/credential.record.dto.ts    |  20 ++-
 libs/dtos/src/dtos/generics/did.record.dto.ts |  12 ++
 .../src/dtos/generics/message.record.dto.ts   |  14 ++
 .../src/dtos/generics/proof.formatData.dto.ts |   8 +
 .../src/dtos/generics/proof.record.dto.ts     |  11 ++
 .../src/dtos/generics/schema.record.dto.ts    |  13 ++
 .../create.invitation.response.dto.ts         |  15 ++
 .../gateway.accepted.response.dto.ts          |   8 +
 26 files changed, 488 insertions(+), 370 deletions(-)

diff --git a/agent-swagger.json b/agent-swagger.json
index 92c6d0a9..996110fd 100644
--- a/agent-swagger.json
+++ b/agent-swagger.json
@@ -1461,9 +1461,6 @@
             ],
             "type": "string"
           },
-          "credentialRecordType": {
-            "type": "string"
-          },
           "connectionId": {
             "type": "string"
           },
@@ -1479,7 +1476,6 @@
         },
         "required": [
           "state",
-          "credentialRecordType",
           "tags"
         ]
       },
diff --git a/apps/attestation-manager/src/app/app.controller.ts b/apps/attestation-manager/src/app/app.controller.ts
index efe1a2f8..5d4176c7 100644
--- a/apps/attestation-manager/src/app/app.controller.ts
+++ b/apps/attestation-manager/src/app/app.controller.ts
@@ -40,10 +40,9 @@ export class AppController {
         event as CloudEventDto<typeof payload.data>,
       );
 
-      const response = new GatewayAcceptedResponseDto();
-      response.id = event.id;
-
-      return response;
+      return GatewayAcceptedResponseDto.fromJson({
+        id: event.id,
+      });
     } catch (e) {
       this.logger.debug(JSON.stringify(e, null, 2));
       if (e instanceof Error) {
@@ -76,10 +75,9 @@ export class AppController {
         event as CloudEventDto<typeof payload.data>,
       );
 
-      const response = new GatewayAcceptedResponseDto();
-      response.id = event.id;
-
-      return response;
+      return GatewayAcceptedResponseDto.fromJson({
+        id: event.id,
+      });
     } catch (e) {
       this.logger.debug(JSON.stringify(e, null, 2));
       if (e instanceof Error) {
@@ -109,10 +107,9 @@ export class AppController {
         event as CloudEventDto<typeof payload.data>,
       );
 
-      const response = new GatewayAcceptedResponseDto();
-      response.id = event.id;
-
-      return response;
+      return GatewayAcceptedResponseDto.fromJson({
+        id: event.id,
+      });
     } catch (e) {
       this.logger.debug(JSON.stringify(e, null, 2));
       if (e instanceof Error) {
diff --git a/apps/connection-manager/src/app/app.controller.ts b/apps/connection-manager/src/app/app.controller.ts
index 98d111dc..067c9778 100644
--- a/apps/connection-manager/src/app/app.controller.ts
+++ b/apps/connection-manager/src/app/app.controller.ts
@@ -37,10 +37,9 @@ export class AppController {
         event as CloudEventDto<typeof payload.data>,
       );
 
-      const response = new GatewayAcceptedResponseDto();
-      response.id = event.id;
-
-      return response;
+      return GatewayAcceptedResponseDto.fromJson({
+        id: event.id,
+      });
     } catch (e) {
       this.logger.debug(JSON.stringify(e, null, 2));
       if (e instanceof Error) {
diff --git a/apps/proof-manager/src/app/app.controller.ts b/apps/proof-manager/src/app/app.controller.ts
index c95b71c5..889c4b14 100644
--- a/apps/proof-manager/src/app/app.controller.ts
+++ b/apps/proof-manager/src/app/app.controller.ts
@@ -37,10 +37,9 @@ export class AppController {
         event as CloudEventDto<typeof payload.data>,
       );
 
-      const response = new GatewayAcceptedResponseDto();
-      response.id = event.id;
-
-      return response;
+      return GatewayAcceptedResponseDto.fromJson({
+        id: event.id,
+      });
     } catch (e) {
       this.logger.debug(JSON.stringify(e, null, 2));
       if (e instanceof Error) {
diff --git a/libs/askar/src/askar/services/agent-event-listener.service.ts b/libs/askar/src/askar/services/agent-event-listener.service.ts
index d1dde4d6..cc596095 100644
--- a/libs/askar/src/askar/services/agent-event-listener.service.ts
+++ b/libs/askar/src/askar/services/agent-event-listener.service.ts
@@ -93,18 +93,17 @@ export class AgentEventListenerService implements OnModuleInit {
             messageRecord.connectionId,
           );
           const label = connectionInfo?.theirLabel || "";
-          const dto = new MessageRecordDto();
-
-          dto.id = messageRecord.id;
-          dto.createdAt = messageRecord.createdAt;
-          dto.updatedAt = messageRecord.updatedAt;
-          dto.connectionId = messageRecord.connectionId;
-          dto.role = messageRecord.role;
-          dto.content = messageRecord.content;
-          dto.sentTime = messageRecord.sentTime;
-          dto.from =
-            messageRecord.role === BasicMessageRole.Receiver ? label : "";
-          dto.to = messageRecord.role === BasicMessageRole.Sender ? label : "";
+          const dto = MessageRecordDto.fromJson({
+            id: messageRecord.id,
+            createdAt: messageRecord.createdAt,
+            updatedAt: messageRecord.updatedAt,
+            connectionId: messageRecord.connectionId,
+            role: messageRecord.role,
+            content: messageRecord.content,
+            sentTime: messageRecord.sentTime,
+            from: messageRecord.role === BasicMessageRole.Receiver ? label : "",
+            to: messageRecord.role === BasicMessageRole.Sender ? label : "",
+          });
 
           if (this.agentConfig?.agentIsRest) {
             this.logger.debug(
diff --git a/libs/askar/src/askar/services/agent.anoncreds.service.ts b/libs/askar/src/askar/services/agent.anoncreds.service.ts
index 34a454dc..65efbc71 100644
--- a/libs/askar/src/askar/services/agent.anoncreds.service.ts
+++ b/libs/askar/src/askar/services/agent.anoncreds.service.ts
@@ -24,17 +24,16 @@ export class AgentAnoncredsService {
     );
 
     const schemaResponses = schemaRecords.map((singleSchemaRes) => {
-      const schemaResponse = new SchemaRecordDto();
-      schemaResponse.id = singleSchemaRes.schemaId;
-      schemaResponse.createdAt = singleSchemaRes.createdAt;
-      schemaResponse.updatedAt = singleSchemaRes.updatedAt;
-      schemaResponse.name = singleSchemaRes.schema.name;
-      schemaResponse.attributes = singleSchemaRes.schema.attrNames;
-      schemaResponse.version = singleSchemaRes.schema.version;
-      schemaResponse.issuerId = singleSchemaRes.schema.issuerId;
-      schemaResponse.methodName = singleSchemaRes.methodName;
-
-      return schemaResponse;
+      return SchemaRecordDto.fromJson({
+        id: singleSchemaRes.schemaId,
+        createdAt: singleSchemaRes.createdAt,
+        updatedAt: singleSchemaRes.updatedAt,
+        name: singleSchemaRes.schema.name,
+        attributes: singleSchemaRes.schema.attrNames,
+        version: singleSchemaRes.schema.version,
+        issuerId: singleSchemaRes.schema.issuerId,
+        methodName: singleSchemaRes.methodName,
+      });
     });
 
     return schemaResponses;
@@ -49,14 +48,13 @@ export class AgentAnoncredsService {
       throw new EntityNotFoundError();
     }
 
-    const schemaResponse = new SchemaRecordDto();
-    schemaResponse.id = agentResponse.schemaId;
-    schemaResponse.name = agentResponse.schema.name;
-    schemaResponse.attributes = agentResponse.schema.attrNames;
-    schemaResponse.version = agentResponse.schema.version;
-    schemaResponse.issuerId = agentResponse.schema.issuerId;
-
-    return schemaResponse;
+    return SchemaRecordDto.fromJson({
+      id: agentResponse.schemaId,
+      name: agentResponse.schema.name,
+      attributes: agentResponse.schema.attrNames,
+      version: agentResponse.schema.version,
+      issuerId: agentResponse.schema.issuerId,
+    });
   };
 
   createSchema = async (
@@ -79,15 +77,13 @@ export class AgentAnoncredsService {
       throw new SchemaNotCreatedError();
     }
 
-    const response = new SchemaRecordDto();
-
-    response.name = schemaResult.schemaState.schema.name;
-    response.id = schemaResult.schemaState.schemaId;
-    response.issuerId = schemaResult.schemaState.schema.issuerId;
-    response.version = schemaResult.schemaState.schema.version;
-    response.attributes = schemaResult.schemaState.schema.attrNames;
-
-    return response;
+    return SchemaRecordDto.fromJson({
+      id: schemaResult.schemaState.schemaId,
+      name: schemaResult.schemaState.schema.name,
+      attributes: schemaResult.schemaState.schema.attrNames,
+      version: schemaResult.schemaState.schema.version,
+      issuerId: schemaResult.schemaState.schema.issuerId,
+    });
   };
 
   fetchCredentialDefinitions = async (): Promise<CreddefRecordDto[]> => {
@@ -102,13 +98,14 @@ export class AgentAnoncredsService {
 
     const response: Array<CreddefRecordDto> = [];
     for (const credDef of credentialDefinitions) {
-      const cd = new CreddefRecordDto();
-      cd.id = credDef.credentialDefinitionId;
-      cd.createdAt = credDef.createdAt;
-      cd.updatedAt = credDef.updatedAt;
-      cd.schemaId = credDef.credentialDefinition.schemaId;
-      cd.issuerId = credDef.credentialDefinition.issuerId;
-      cd.tag = credDef.credentialDefinition.tag;
+      const cd = CreddefRecordDto.fromJson({
+        id: credDef.credentialDefinitionId,
+        createdAt: credDef.createdAt,
+        updatedAt: credDef.updatedAt,
+        schemaId: credDef.credentialDefinition.schemaId,
+        issuerId: credDef.credentialDefinition.issuerId,
+        tag: credDef.credentialDefinition.tag,
+      });
       response.push(cd);
     }
 
@@ -128,15 +125,14 @@ export class AgentAnoncredsService {
       throw new EntityNotFoundError();
     }
 
-    const cd = new CreddefRecordDto();
-    cd.id = credDef.credentialDefinitionId;
-    cd.createdAt = credDef.createdAt;
-    cd.updatedAt = credDef.updatedAt;
-    cd.schemaId = credDef.credentialDefinition.schemaId;
-    cd.issuerId = credDef.credentialDefinition.issuerId;
-    cd.tag = credDef.credentialDefinition.tag;
-
-    return cd;
+    return CreddefRecordDto.fromJson({
+      id: credDef.credentialDefinitionId,
+      createdAt: credDef.createdAt,
+      updatedAt: credDef.updatedAt,
+      schemaId: credDef.credentialDefinition.schemaId,
+      issuerId: credDef.credentialDefinition.issuerId,
+      tag: credDef.credentialDefinition.tag,
+    });
   };
 
   createCredentialDefinition = async (
@@ -144,7 +140,7 @@ export class AgentAnoncredsService {
   ): Promise<CreddefRecordDto> => {
     const dids = await this.askar.agent.dids.getCreatedDids({ method: "indy" });
 
-    const credDef =
+    const response =
       await this.askar.agent.modules.anoncreds.registerCredentialDefinition({
         credentialDefinition: {
           tag: credentialDefinitionDto.tag,
@@ -156,18 +152,12 @@ export class AgentAnoncredsService {
         },
       });
 
-    if (credDef.credentialDefinitionState.state !== "finished") {
+    if (response.credentialDefinitionState.state !== "finished") {
       throw new CredentialNotCreatedError();
     }
 
-    const response = new CreddefRecordDto();
-    response.id = credDef.credentialDefinitionState.credentialDefinitionId;
-    response.schemaId =
-      credDef.credentialDefinitionState.credentialDefinition.schemaId;
-    response.issuerId =
-      credDef.credentialDefinitionState.credentialDefinition.issuerId;
-    response.tag = credDef.credentialDefinitionState.credentialDefinition.tag;
-
-    return response;
+    return this.getCredentialDefinitionById(
+      response.credentialDefinitionState.credentialDefinitionId,
+    );
   };
 }
diff --git a/libs/askar/src/askar/services/agent.basicMessages.service.ts b/libs/askar/src/askar/services/agent.basicMessages.service.ts
index 5f9454ea..6a2d86c9 100644
--- a/libs/askar/src/askar/services/agent.basicMessages.service.ts
+++ b/libs/askar/src/askar/services/agent.basicMessages.service.ts
@@ -62,18 +62,19 @@ export class AgentBasicMessagesService {
       const connection = grouppedConnections[message.connectionId];
       const label = connection?.theirLabel || "";
 
-      const t = new MessageRecordDto();
-      t.id = message.id;
-      t.createdAt = message.createdAt;
-      t.updatedAt = message.updatedAt;
-      t.connectionId = message.connectionId;
-      t.role = message.role;
-      t.content = message.content;
-      t.sentTime = message.sentTime;
-      t.from = message.role === BasicMessageRole.Receiver ? label : "";
-      t.to = message.role === BasicMessageRole.Sender ? label : "";
-
-      response.push(t);
+      const dto = MessageRecordDto.fromJson({
+        id: message.id,
+        createdAt: message.createdAt,
+        updatedAt: message.updatedAt,
+        connectionId: message.connectionId,
+        role: message.role,
+        content: message.content,
+        sentTime: message.sentTime,
+        from: message.role === BasicMessageRole.Receiver ? label : "",
+        to: message.role === BasicMessageRole.Sender ? label : "",
+      });
+
+      response.push(dto);
     }
 
     return response;
@@ -91,18 +92,17 @@ export class AgentBasicMessagesService {
       dto.connectionId,
     );
 
-    const response = new MessageRecordDto();
-    response.id = messageRecord.id;
-    response.createdAt = messageRecord.createdAt;
-    response.updatedAt = messageRecord.updatedAt;
-    response.connectionId = messageRecord.connectionId;
-    response.role = messageRecord.role;
-    response.content = messageRecord.content;
-    response.sentTime = messageRecord.sentTime;
-    response.from = "";
-    response.to = connRecord?.theirLabel || "";
-
-    return response;
+    return MessageRecordDto.fromJson({
+      id: messageRecord.id,
+      createdAt: messageRecord.createdAt,
+      updatedAt: messageRecord.updatedAt,
+      connectionId: messageRecord.connectionId,
+      role: messageRecord.role,
+      content: messageRecord.content,
+      sentTime: messageRecord.sentTime,
+      from: "",
+      to: connRecord?.theirLabel || "",
+    });
   };
 
   deleteMessageById = async (id: string): Promise<void> => {
diff --git a/libs/askar/src/askar/services/agent.connections.service.ts b/libs/askar/src/askar/services/agent.connections.service.ts
index 8e389e87..3140ac0a 100644
--- a/libs/askar/src/askar/services/agent.connections.service.ts
+++ b/libs/askar/src/askar/services/agent.connections.service.ts
@@ -1,10 +1,11 @@
 import { Injectable, Logger } from "@nestjs/common";
 import { AskarService } from "./askar.service";
 import {
+  BaseRecordDto,
   ConnectionRecordDto,
   EntityNotFoundError,
-  BaseRecordDto,
 } from "@ocm-engine/dtos";
+import { DidExchangeState } from "@credo-ts/core";
 
 @Injectable()
 export class AgentConnectionsService {
@@ -19,20 +20,19 @@ export class AgentConnectionsService {
     );
 
     const connectionArray = agentResponse.map((singleConnectionRes) => {
-      const connectionResponse = new ConnectionRecordDto();
-      connectionResponse.id = singleConnectionRes.id;
-      connectionResponse.state = singleConnectionRes.state;
-      connectionResponse.connectionName = singleConnectionRes.theirLabel;
-      connectionResponse.alias = singleConnectionRes.alias;
-      connectionResponse.did = singleConnectionRes.did;
-      connectionResponse.theirDid = singleConnectionRes.theirDid;
-      connectionResponse.invitationDid = singleConnectionRes.invitationDid;
-      connectionResponse.outOfBandId = singleConnectionRes.outOfBandId;
-      connectionResponse.createdAt = singleConnectionRes.createdAt;
-      connectionResponse.updatedAt = singleConnectionRes.updatedAt;
-      connectionResponse.imageUrl = singleConnectionRes.imageUrl;
-
-      return connectionResponse;
+      return ConnectionRecordDto.fromJson({
+        id: singleConnectionRes.id,
+        createdAt: singleConnectionRes.createdAt,
+        updatedAt: singleConnectionRes.updatedAt,
+        state: singleConnectionRes.state,
+        connectionName: singleConnectionRes.theirLabel,
+        alias: singleConnectionRes.alias,
+        did: singleConnectionRes.did,
+        theirDid: singleConnectionRes.theirDid,
+        invitationDid: singleConnectionRes.invitationDid,
+        outOfBandId: singleConnectionRes.outOfBandId,
+        imageUrl: singleConnectionRes.imageUrl,
+      });
     });
 
     return connectionArray;
@@ -43,20 +43,19 @@ export class AgentConnectionsService {
       await this.askar.agent.connections.findAllByOutOfBandId(oobId);
 
     const connectionArray = connectionRecords.map((singleConnectionRes) => {
-      const connectionResponse = new ConnectionRecordDto();
-      connectionResponse.id = singleConnectionRes.id;
-      connectionResponse.state = singleConnectionRes.state;
-      connectionResponse.connectionName = singleConnectionRes.theirLabel;
-      connectionResponse.alias = singleConnectionRes.alias;
-      connectionResponse.did = singleConnectionRes.did;
-      connectionResponse.theirDid = singleConnectionRes.theirDid;
-      connectionResponse.invitationDid = singleConnectionRes.invitationDid;
-      connectionResponse.outOfBandId = singleConnectionRes.outOfBandId;
-      connectionResponse.createdAt = singleConnectionRes.createdAt;
-      connectionResponse.updatedAt = singleConnectionRes.updatedAt;
-      connectionResponse.imageUrl = singleConnectionRes.imageUrl;
-
-      return connectionResponse;
+      return ConnectionRecordDto.fromJson({
+        id: singleConnectionRes.id,
+        createdAt: singleConnectionRes.createdAt,
+        updatedAt: singleConnectionRes.updatedAt,
+        state: singleConnectionRes.state,
+        connectionName: singleConnectionRes.theirLabel,
+        alias: singleConnectionRes.alias,
+        did: singleConnectionRes.did,
+        theirDid: singleConnectionRes.theirDid,
+        invitationDid: singleConnectionRes.invitationDid,
+        outOfBandId: singleConnectionRes.outOfBandId,
+        imageUrl: singleConnectionRes.imageUrl,
+      });
     });
 
     return connectionArray;
@@ -69,20 +68,19 @@ export class AgentConnectionsService {
       throw new EntityNotFoundError();
     }
 
-    const connectionResponse = new ConnectionRecordDto();
-    connectionResponse.id = agentResponse.id;
-    connectionResponse.state = agentResponse.state;
-    connectionResponse.connectionName = agentResponse.theirLabel;
-    connectionResponse.alias = agentResponse.alias;
-    connectionResponse.did = agentResponse.did;
-    connectionResponse.theirDid = agentResponse.theirDid;
-    connectionResponse.invitationDid = agentResponse.invitationDid;
-    connectionResponse.outOfBandId = agentResponse.outOfBandId;
-    connectionResponse.createdAt = agentResponse.createdAt;
-    connectionResponse.updatedAt = agentResponse.updatedAt;
-    connectionResponse.imageUrl = agentResponse.imageUrl;
-
-    return connectionResponse;
+    return ConnectionRecordDto.fromJson({
+      id: agentResponse.id,
+      state: agentResponse.state,
+      connectionName: agentResponse.theirLabel,
+      alias: agentResponse.alias,
+      did: agentResponse.did,
+      theirDid: agentResponse.theirDid,
+      invitationDid: agentResponse.invitationDid,
+      outOfBandId: agentResponse.outOfBandId,
+      createdAt: agentResponse.createdAt,
+      updatedAt: agentResponse.updatedAt,
+      imageUrl: agentResponse.imageUrl,
+    });
   };
 
   deleteConnectionById = async (id: string): Promise<void> => {
@@ -98,9 +96,8 @@ export class AgentConnectionsService {
       withReturnRouting: false,
     });
 
-    const response = new BaseRecordDto();
-    response.id = msg.toJSON()["@id"];
-
-    return response;
+    return BaseRecordDto.fromJson({
+      id: msg.toJSON()["@id"],
+    });
   };
 }
diff --git a/libs/askar/src/askar/services/agent.credentials.service.ts b/libs/askar/src/askar/services/agent.credentials.service.ts
index 8cfbbbad..53553672 100644
--- a/libs/askar/src/askar/services/agent.credentials.service.ts
+++ b/libs/askar/src/askar/services/agent.credentials.service.ts
@@ -57,13 +57,15 @@ export class AgentCredentialsService {
 
       const shortCredentialUrl = `${this.askar.agentConfig.agentPeerAddress}/invitations/${outOfBandRecord.outOfBandInvitation.id}`;
 
-      const dto = new CredentialRecordDto();
-      dto.id = credentialRecord.id;
-      dto.state = credentialRecord.state;
-      dto.connectionId = credentialRecord.connectionId;
-      dto.attributes = credentialRecord.credentialAttributes;
-      dto.createdAt = credentialRecord.createdAt;
-      dto.tags = credentialRecord.getTags();
+      const dto = CredentialRecordDto.fromJson({
+        id: credentialRecord.id,
+        createdAt: credentialRecord.createdAt,
+        updatedAt: credentialRecord.updatedAt,
+        state: credentialRecord.state,
+        connectionId: credentialRecord.connectionId,
+        attributes: credentialRecord.credentialAttributes,
+        tags: credentialRecord.getTags(),
+      });
 
       return {
         credentialUrl: credentialUrl,
@@ -86,13 +88,15 @@ export class AgentCredentialsService {
     credentialExchangeRecord.setTag("xRole", "issuer");
     await this.askar.agent.credentials.update(credentialExchangeRecord);
 
-    const dto = new CredentialRecordDto();
-    dto.id = credentialExchangeRecord.id;
-    dto.state = credentialExchangeRecord.state;
-    dto.connectionId = credentialExchangeRecord.connectionId;
-    dto.attributes = credentialExchangeRecord.credentialAttributes;
-    dto.createdAt = credentialExchangeRecord.createdAt;
-    dto.tags = credentialExchangeRecord.getTags();
+    const dto = CredentialRecordDto.fromJson({
+      id: credentialExchangeRecord.id,
+      createdAt: credentialExchangeRecord.createdAt,
+      updatedAt: credentialExchangeRecord.updatedAt,
+      state: credentialExchangeRecord.state,
+      connectionId: credentialExchangeRecord.connectionId,
+      attributes: credentialExchangeRecord.credentialAttributes,
+      tags: credentialExchangeRecord.getTags(),
+    });
 
     return {
       credentialUrl: null,
@@ -131,15 +135,15 @@ export class AgentCredentialsService {
       credentialRecordId: record.id,
     });
 
-    const response = new CredentialRecordDto();
-    response.id = acceptedRecord.id;
-    response.state = acceptedRecord.state;
-    response.connectionId = acceptedRecord.connectionId;
-    response.attributes = acceptedRecord.credentialAttributes;
-    response.createdAt = acceptedRecord.createdAt;
-    response.tags = acceptedRecord.getTags();
-
-    return response;
+    return CredentialRecordDto.fromJson({
+      id: acceptedRecord.id,
+      createdAt: acceptedRecord.createdAt,
+      updatedAt: acceptedRecord.updatedAt,
+      state: acceptedRecord.state,
+      connectionId: acceptedRecord.connectionId,
+      attributes: acceptedRecord.credentialAttributes,
+      tags: acceptedRecord.getTags(),
+    });
   };
 
   acceptConnectionCredential = async (
@@ -150,15 +154,15 @@ export class AgentCredentialsService {
         credentialRecordId,
       });
 
-    const response = new CredentialRecordDto();
-    response.id = credentialExchangeRecord.id;
-    response.state = credentialExchangeRecord.state;
-    response.connectionId = credentialExchangeRecord.connectionId;
-    response.attributes = credentialExchangeRecord.credentialAttributes;
-    response.createdAt = credentialExchangeRecord.createdAt;
-    response.tags = credentialExchangeRecord.getTags();
-
-    return response;
+    return CredentialRecordDto.fromJson({
+      id: credentialExchangeRecord.id,
+      createdAt: credentialExchangeRecord.createdAt,
+      updatedAt: credentialExchangeRecord.updatedAt,
+      state: credentialExchangeRecord.state,
+      connectionId: credentialExchangeRecord.connectionId,
+      attributes: credentialExchangeRecord.credentialAttributes,
+      tags: credentialExchangeRecord.getTags(),
+    });
   };
 
   declineCredential = async (
@@ -173,15 +177,15 @@ export class AgentCredentialsService {
       description: "Decline offer",
     });
 
-    const response = new CredentialRecordDto();
-    response.id = credentialExchangeRecord.id;
-    response.state = credentialExchangeRecord.state;
-    response.connectionId = credentialExchangeRecord.connectionId;
-    response.attributes = credentialExchangeRecord.credentialAttributes;
-    response.createdAt = credentialExchangeRecord.createdAt;
-    response.tags = credentialExchangeRecord.getTags();
-
-    return response;
+    return CredentialRecordDto.fromJson({
+      id: credentialExchangeRecord.id,
+      createdAt: credentialExchangeRecord.createdAt,
+      updatedAt: credentialExchangeRecord.updatedAt,
+      state: credentialExchangeRecord.state,
+      connectionId: credentialExchangeRecord.connectionId,
+      attributes: credentialExchangeRecord.credentialAttributes,
+      tags: credentialExchangeRecord.getTags(),
+    });
   };
 
   fetchCredentials = async (
@@ -213,14 +217,16 @@ export class AgentCredentialsService {
 
     const response: CredentialRecordDto[] = [];
     for (const offer of credentials) {
-      const t = new CredentialRecordDto();
-      t.id = offer.id;
-      t.state = offer.state;
-      t.connectionId = offer.connectionId;
-      t.createdAt = offer.createdAt;
-      t.attributes = offer.credentialAttributes;
-      t.tags = offer.getTags();
-      response.push(t);
+      const dto = CredentialRecordDto.fromJson({
+        id: offer.id,
+        createdAt: offer.createdAt,
+        updatedAt: offer.updatedAt,
+        state: offer.state,
+        connectionId: offer.connectionId,
+        attributes: offer.credentialAttributes,
+        tags: offer.getTags(),
+      });
+      response.push(dto);
     }
 
     return response;
@@ -237,15 +243,15 @@ export class AgentCredentialsService {
       throw new EntityNotFoundError();
     }
 
-    const credential = new CredentialRecordDto();
-    credential.id = credentialRecord.id;
-    credential.state = credentialRecord.state;
-    credential.connectionId = credentialRecord.connectionId;
-    credential.createdAt = credentialRecord.createdAt;
-    credential.attributes = credentialRecord.credentialAttributes;
-    credential.tags = credentialRecord.getTags();
-
-    return credential;
+    return CredentialRecordDto.fromJson({
+      id: credentialRecord.id,
+      createdAt: credentialRecord.createdAt,
+      updatedAt: credentialRecord.updatedAt,
+      state: credentialRecord.state,
+      connectionId: credentialRecord.connectionId,
+      attributes: credentialRecord.credentialAttributes,
+      tags: credentialRecord.getTags(),
+    });
   };
 
   getCredentialFormatDataById = async (
@@ -259,17 +265,15 @@ export class AgentCredentialsService {
       throw new EntityNotFoundError();
     }
 
-    const dto = new CredentialFormatDataDto();
-    dto.proposalAttributes = formatData.proposalAttributes;
-    dto.offerAttributes = formatData.offerAttributes;
-    dto.anoncredsProposal = formatData.proposal?.anoncreds;
-    dto.anoncredsOffer = formatData.offer?.anoncreds;
-    dto.anoncredsRequest = formatData.request?.anoncreds;
-    dto.anoncredsCredential = formatData.credential?.anoncreds;
-
-    dto.all = formatData;
-
-    return dto;
+    return CredentialFormatDataDto.fromJson({
+      proposalAttributes: formatData.proposalAttributes,
+      offerAttributes: formatData.offerAttributes,
+      anoncredsProposal: formatData.proposal?.anoncreds,
+      anoncredsOffer: formatData.offer?.anoncreds,
+      anoncredsRequest: formatData.request?.anoncreds,
+      anoncredsCredential: formatData.credential?.anoncreds,
+      all: formatData,
+    });
   };
 
   deleteCredentialById = async (id: string): Promise<void> => {
diff --git a/libs/askar/src/askar/services/agent.dids.service.ts b/libs/askar/src/askar/services/agent.dids.service.ts
index 7cb1cf0b..3b92fffd 100644
--- a/libs/askar/src/askar/services/agent.dids.service.ts
+++ b/libs/askar/src/askar/services/agent.dids.service.ts
@@ -14,15 +14,16 @@ export class AgentDidsService {
   getCreatedDids = async (): Promise<DidRecordDto[]> => {
     const didRecords = await this.askar.agent.dids.getCreatedDids();
     return didRecords.map((p) => {
-      const dto = new DidRecordDto();
       const tags = p.getTags();
-
-      dto.did = p.did;
-      dto.role = p.role;
-      dto.method = tags.method;
-      dto.tags = tags;
-
-      return dto;
+      return DidRecordDto.fromJson({
+        id: p.id,
+        createdAt: p.createdAt,
+        updatedAt: p.updatedAt,
+        did: p.did,
+        role: p.role,
+        method: tags.method,
+        tags: tags,
+      });
     });
   };
 }
diff --git a/libs/askar/src/askar/services/agent.jsonld.service.ts b/libs/askar/src/askar/services/agent.jsonld.service.ts
index c0f8029e..972c8fda 100644
--- a/libs/askar/src/askar/services/agent.jsonld.service.ts
+++ b/libs/askar/src/askar/services/agent.jsonld.service.ts
@@ -207,13 +207,15 @@ export class AgentJsonldService {
 
       const shortCredentialUrl = `${this.askar.agentConfig.agentPeerAddress}/invitations/${outOfBandRecord.outOfBandInvitation.id}`;
 
-      const dto = new CredentialRecordDto();
-      dto.id = credentialRecord.id;
-      dto.state = credentialRecord.state;
-      dto.connectionId = credentialRecord.connectionId;
-      dto.attributes = credentialRecord.credentialAttributes;
-      dto.createdAt = credentialRecord.createdAt;
-      dto.tags = credentialRecord.getTags();
+      const dto = CredentialRecordDto.fromJson({
+        id: credentialRecord.id,
+        createdAt: credentialRecord.createdAt,
+        updatedAt: credentialRecord.updatedAt,
+        state: credentialRecord.state,
+        connectionId: credentialRecord.connectionId,
+        attributes: credentialRecord.credentialAttributes,
+        tags: credentialRecord.getTags(),
+      });
 
       return {
         credentialUrl: credentialUrl,
@@ -243,13 +245,15 @@ export class AgentJsonldService {
     credentialExchangeRecord.setTag("xRole", "issuer");
     await this.askar.agent.credentials.update(credentialExchangeRecord);
 
-    const dto = new CredentialRecordDto();
-    dto.id = credentialExchangeRecord.id;
-    dto.state = credentialExchangeRecord.state;
-    dto.connectionId = credentialExchangeRecord.connectionId;
-    dto.attributes = credentialExchangeRecord.credentialAttributes;
-    dto.createdAt = credentialExchangeRecord.createdAt;
-    dto.tags = credentialExchangeRecord.getTags();
+    const dto = CredentialRecordDto.fromJson({
+      id: credentialExchangeRecord.id,
+      createdAt: credentialExchangeRecord.createdAt,
+      updatedAt: credentialExchangeRecord.updatedAt,
+      state: credentialExchangeRecord.state,
+      connectionId: credentialExchangeRecord.connectionId,
+      attributes: credentialExchangeRecord.credentialAttributes,
+      tags: credentialExchangeRecord.getTags(),
+    });
 
     return {
       credentialUrl: null,
diff --git a/libs/askar/src/askar/services/agent.oob.service.ts b/libs/askar/src/askar/services/agent.oob.service.ts
index 03beebd5..18476490 100644
--- a/libs/askar/src/askar/services/agent.oob.service.ts
+++ b/libs/askar/src/askar/services/agent.oob.service.ts
@@ -21,8 +21,6 @@ export class AgentOobService {
       createInvitationRequestDto,
     );
 
-    const response = new CreateInvitationResponseDto();
-
     let longUrl = outOfBoundRecord.outOfBandInvitation.toUrl({
       domain: this.askar.agentConfig.agentPeerAddress,
     });
@@ -35,15 +33,15 @@ export class AgentOobService {
     }
 
     //TODO: should we replace the short url with agentOobUrl if we do this we should have a redirect in ingress
-    response.shortInvitationUrl = `${this.askar.agentConfig.agentPeerAddress}/invitations/${outOfBoundRecord.outOfBandInvitation.id}`;
-    response.outOfBandId = outOfBoundRecord.id;
-    response.createdAt = outOfBoundRecord.createdAt;
-    response.updatedAt = outOfBoundRecord.updatedAt;
-    response.role = outOfBoundRecord.role;
-    response.state = outOfBoundRecord.state;
-    response.invitationUrl = longUrl;
-
-    return response;
+    return CreateInvitationResponseDto.fromJson({
+      createdAt: outOfBoundRecord.createdAt,
+      updatedAt: outOfBoundRecord.updatedAt,
+      outOfBandId: outOfBoundRecord.id,
+      role: outOfBoundRecord.role,
+      state: outOfBoundRecord.state,
+      invitationUrl: longUrl,
+      shortInvitationUrl: `${this.askar.agentConfig.agentPeerAddress}/invitations/${outOfBoundRecord.outOfBandInvitation.id}`,
+    });
   };
 
   acceptInvitation = async (
@@ -56,19 +54,18 @@ export class AgentOobService {
       throw new EntityNotFoundError();
     }
 
-    const response = new ConnectionRecordDto();
-    response.connectionName = connectionRecord.theirLabel;
-    response.state = connectionRecord.state;
-    response.id = connectionRecord.id;
-    response.did = connectionRecord.did;
-    response.theirDid = connectionRecord.theirDid;
-    response.invitationDid = connectionRecord.invitationDid;
-    response.outOfBandId = connectionRecord.outOfBandId;
-    response.createdAt = connectionRecord.createdAt;
-    response.updatedAt = connectionRecord.updatedAt;
-    response.imageUrl = connectionRecord.imageUrl;
-
-    return response;
+    return ConnectionRecordDto.fromJson({
+      connectionName: connectionRecord.theirLabel,
+      state: connectionRecord.state,
+      id: connectionRecord.id,
+      did: connectionRecord.did,
+      theirDid: connectionRecord.theirDid,
+      invitationDid: connectionRecord.invitationDid,
+      outOfBandId: connectionRecord.outOfBandId,
+      createdAt: connectionRecord.createdAt,
+      updatedAt: connectionRecord.updatedAt,
+      imageUrl: connectionRecord.imageUrl,
+    });
   };
 
   deleteInvitationById = async (id: string) => {
@@ -102,17 +99,17 @@ export class AgentOobService {
     );
 
     const invitationsResponse = invitations.map((invitation) => {
-      const response = new CreateInvitationResponseDto();
-      response.invitationUrl = invitation.outOfBandInvitation.toUrl({
-        domain: this.askar.agentConfig.agentPeerAddress,
+      return CreateInvitationResponseDto.fromJson({
+        createdAt: invitation.createdAt,
+        updatedAt: invitation.updatedAt,
+        outOfBandId: invitation.id,
+        role: invitation.role,
+        state: invitation.state,
+        invitationUrl: invitation.outOfBandInvitation.toUrl({
+          domain: this.askar.agentConfig.agentPeerAddress,
+        }),
+        shortInvitationUrl: `${this.askar.agentConfig.agentPeerAddress}/invitations/${invitation.outOfBandInvitation.id}`,
       });
-      response.shortInvitationUrl = `${this.askar.agentConfig.agentPeerAddress}/invitations/${invitation.outOfBandInvitation.id}`;
-      response.outOfBandId = invitation.id;
-      response.createdAt = invitation.createdAt;
-      response.updatedAt = invitation.updatedAt;
-      response.role = invitation.role;
-      response.state = invitation.state;
-      return response;
     });
 
     return invitationsResponse;
@@ -121,16 +118,16 @@ export class AgentOobService {
   getInvitationById = async (oobId: string) => {
     const invitation = await this.askar.agent.oob.getById(oobId);
 
-    const response = new CreateInvitationResponseDto();
-    response.invitationUrl = invitation.outOfBandInvitation.toUrl({
-      domain: this.askar.agentConfig.agentPeerAddress,
+    return CreateInvitationResponseDto.fromJson({
+      createdAt: invitation.createdAt,
+      updatedAt: invitation.updatedAt,
+      outOfBandId: invitation.id,
+      role: invitation.role,
+      state: invitation.state,
+      invitationUrl: invitation.outOfBandInvitation.toUrl({
+        domain: this.askar.agentConfig.agentPeerAddress,
+      }),
+      shortInvitationUrl: `${this.askar.agentConfig.agentPeerAddress}/invitations/${invitation.outOfBandInvitation.id}`,
     });
-    response.shortInvitationUrl = `${this.askar.agentConfig.agentPeerAddress}/invitations/${invitation.outOfBandInvitation.id}`;
-    response.outOfBandId = invitation.id;
-    response.createdAt = invitation.createdAt;
-    response.updatedAt = invitation.updatedAt;
-    response.role = invitation.role;
-    response.state = invitation.state;
-    return response;
   };
 }
diff --git a/libs/askar/src/askar/services/agent.proofs.service.ts b/libs/askar/src/askar/services/agent.proofs.service.ts
index fa4c5f3c..8f6bb40b 100644
--- a/libs/askar/src/askar/services/agent.proofs.service.ts
+++ b/libs/askar/src/askar/services/agent.proofs.service.ts
@@ -64,13 +64,14 @@ export class AgentProofsService {
       });
       const shortProofUrl = `${this.askar.agentConfig.agentPeerAddress}/invitations/${outOfBandRecord.outOfBandInvitation.id}`;
 
-      const dto = new ProofRecordDto();
-      dto.id = proofRecord.id;
-      dto.connectionId = proofRecord.connectionId;
-      dto.state = proofRecord.state;
-      dto.updatedAt = proofRecord.updatedAt;
-      dto.createdAt = proofRecord.createdAt;
-      dto.tags = proofRecord.getTags();
+      const dto = ProofRecordDto.fromJson({
+        id: proofRecord.id,
+        createdAt: proofRecord.createdAt,
+        updatedAt: proofRecord.updatedAt,
+        connectionId: proofRecord.connectionId,
+        state: proofRecord.state,
+        tags: proofRecord.getTags(),
+      });
 
       return {
         proofUrl: proofUrl,
@@ -96,18 +97,19 @@ export class AgentProofsService {
     exchangeRecord.setTag("xRole", "requester");
     await this.askar.agent.proofs.update(exchangeRecord);
 
-    const response = new ProofRecordDto();
-    response.id = exchangeRecord.id;
-    response.connectionId = exchangeRecord.connectionId;
-    response.state = exchangeRecord.state;
-    response.updatedAt = exchangeRecord.updatedAt;
-    response.createdAt = exchangeRecord.createdAt;
-    response.tags = exchangeRecord.getTags();
+    const dto = ProofRecordDto.fromJson({
+      id: exchangeRecord.id,
+      createdAt: exchangeRecord.createdAt,
+      updatedAt: exchangeRecord.updatedAt,
+      connectionId: exchangeRecord.connectionId,
+      state: exchangeRecord.state,
+      tags: exchangeRecord.getTags(),
+    });
 
     return {
       proofUrl: null,
       shortProofUrl: null,
-      proofRecord: response,
+      proofRecord: dto,
     };
   };
 
@@ -138,15 +140,15 @@ export class AgentProofsService {
 
     const response: ProofRecordDto[] = [];
     for (const proof of proofs) {
-      const t = new ProofRecordDto();
-      t.id = proof.id;
-      t.connectionId = proof.connectionId;
-      t.state = proof.state;
-      t.updatedAt = proof.updatedAt;
-      t.createdAt = proof.createdAt;
-      t.tags = proof.getTags();
-
-      response.push(t);
+      const dto = ProofRecordDto.fromJson({
+        id: proof.id,
+        createdAt: proof.createdAt,
+        updatedAt: proof.updatedAt,
+        connectionId: proof.connectionId,
+        state: proof.state,
+        tags: proof.getTags(),
+      });
+      response.push(dto);
     }
 
     return response;
@@ -159,16 +161,14 @@ export class AgentProofsService {
       throw new EntityNotFoundError();
     }
 
-    const proofResponse = new ProofRecordDto();
-
-    proofResponse.id = proofRecord.id;
-    proofResponse.connectionId = proofRecord.connectionId;
-    proofResponse.state = proofRecord.state;
-    proofResponse.updatedAt = proofRecord.updatedAt;
-    proofResponse.createdAt = proofRecord.createdAt;
-    proofResponse.tags = proofRecord.getTags();
-
-    return proofResponse;
+    return ProofRecordDto.fromJson({
+      id: proofRecord.id,
+      createdAt: proofRecord.createdAt,
+      updatedAt: proofRecord.updatedAt,
+      connectionId: proofRecord.connectionId,
+      state: proofRecord.state,
+      tags: proofRecord.getTags(),
+    });
   };
 
   getProofFormatDataById = async (
@@ -182,11 +182,11 @@ export class AgentProofsService {
       throw new EntityNotFoundError();
     }
 
-    const dto = new ProofFormatDataDto();
-    dto.anoncredsProposal = formatData.proposal?.anoncreds;
-    dto.anoncredsRequest = formatData.request?.anoncreds;
-    dto.anoncredsPresentation = formatData.presentation?.anoncreds;
-    return dto;
+    return ProofFormatDataDto.fromJson({
+      anoncredsProposal: formatData.proposal?.anoncreds,
+      anoncredsRequest: formatData.request?.anoncreds,
+      anoncredsPresentation: formatData.presentation?.anoncreds,
+    });
   };
 
   proofAcceptanceWait = async (
@@ -244,16 +244,14 @@ export class AgentProofsService {
       proofFormats: requestedCredentials.proofFormats,
     });
 
-    const response = new ProofRecordDto();
-
-    response.id = acceptedRecord.id;
-    response.connectionId = acceptedRecord.connectionId;
-    response.state = acceptedRecord.state;
-    response.updatedAt = acceptedRecord.updatedAt;
-    response.createdAt = acceptedRecord.createdAt;
-    response.tags = acceptedRecord.getTags();
-
-    return response;
+    return ProofRecordDto.fromJson({
+      id: acceptedRecord.id,
+      createdAt: acceptedRecord.createdAt,
+      updatedAt: acceptedRecord.updatedAt,
+      connectionId: acceptedRecord.connectionId,
+      state: acceptedRecord.state,
+      tags: acceptedRecord.getTags(),
+    });
   };
 
   acceptConnectionProof = async (
@@ -274,15 +272,14 @@ export class AgentProofsService {
 
     this.logger.log(JSON.stringify(proof, null, 2));
 
-    const response = new ProofRecordDto();
-    response.id = proof.id;
-    response.connectionId = proof.connectionId;
-    response.state = proof.state;
-    response.updatedAt = proof.updatedAt;
-    response.createdAt = proof.createdAt;
-    response.tags = proof.getTags();
-
-    return response;
+    return ProofRecordDto.fromJson({
+      id: proof.id,
+      createdAt: proof.createdAt,
+      updatedAt: proof.updatedAt,
+      connectionId: proof.connectionId,
+      state: proof.state,
+      tags: proof.getTags(),
+    });
   };
 
   declineProofRequest = async (
@@ -293,15 +290,14 @@ export class AgentProofsService {
       sendProblemReport: true,
     });
 
-    const declineResponse = new ProofRecordDto();
-    declineResponse.id = resultFromDecline.id;
-    declineResponse.connectionId = resultFromDecline.connectionId;
-    declineResponse.state = resultFromDecline.state;
-    declineResponse.updatedAt = resultFromDecline.updatedAt;
-    declineResponse.createdAt = resultFromDecline.createdAt;
-    declineResponse.tags = resultFromDecline.getTags();
-
-    return declineResponse;
+    return ProofRecordDto.fromJson({
+      id: resultFromDecline.id,
+      createdAt: resultFromDecline.createdAt,
+      updatedAt: resultFromDecline.updatedAt,
+      connectionId: resultFromDecline.connectionId,
+      state: resultFromDecline.state,
+      tags: resultFromDecline.getTags(),
+    });
   };
 
   deleteProofById = async (id: string): Promise<void> => {
diff --git a/libs/clients/src/frontend/agent_gen.ts b/libs/clients/src/frontend/agent_gen.ts
index be1e364f..f43da794 100644
--- a/libs/clients/src/frontend/agent_gen.ts
+++ b/libs/clients/src/frontend/agent_gen.ts
@@ -1552,7 +1552,6 @@ export interface CredentialRecordDto {
     createdAt?: Date;
     updatedAt?: Date;
     state: CredentialRecordDtoState;
-    credentialRecordType: string;
     connectionId?: string;
     attributes?: OfferCredentialAttributes[];
     tags: any;
diff --git a/libs/dtos/src/dtos/generics/base.record.dto.ts b/libs/dtos/src/dtos/generics/base.record.dto.ts
index 1654e223..fb477fd9 100644
--- a/libs/dtos/src/dtos/generics/base.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/base.record.dto.ts
@@ -9,4 +9,12 @@ export class BaseRecordDto {
 
   @IsDateString()
   updatedAt?: Date;
+
+  public static fromJson(json: InstanceType<typeof BaseRecordDto>) {
+    const dto = new BaseRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/connection.record.dto.ts b/libs/dtos/src/dtos/generics/connection.record.dto.ts
index 65391af6..4c04a129 100644
--- a/libs/dtos/src/dtos/generics/connection.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/connection.record.dto.ts
@@ -27,4 +27,22 @@ export class ConnectionRecordDto extends BaseRecordDto {
 
   @IsString()
   imageUrl?: string;
+
+  public static override fromJson(
+    json: InstanceType<typeof ConnectionRecordDto>,
+  ) {
+    const dto = new ConnectionRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.state = json.state;
+    dto.connectionName = json.connectionName;
+    dto.alias = json.alias;
+    dto.did = json.did;
+    dto.theirDid = json.theirDid;
+    dto.invitationDid = json.invitationDid;
+    dto.outOfBandId = json.outOfBandId;
+    dto.imageUrl = json.imageUrl;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/creddef.record.dto.ts b/libs/dtos/src/dtos/generics/creddef.record.dto.ts
index 873b8545..9326b7cd 100644
--- a/libs/dtos/src/dtos/generics/creddef.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/creddef.record.dto.ts
@@ -13,4 +13,15 @@ export class CreddefRecordDto extends BaseRecordDto {
   @IsNotEmpty()
   @IsString()
   tag: string;
+
+  public static override fromJson(json: InstanceType<typeof CreddefRecordDto>) {
+    const dto = new CreddefRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.schemaId = json.schemaId;
+    dto.issuerId = json.issuerId;
+    dto.tag = json.tag;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/credential.formatData.dto.ts b/libs/dtos/src/dtos/generics/credential.formatData.dto.ts
index c569babd..a06bac32 100644
--- a/libs/dtos/src/dtos/generics/credential.formatData.dto.ts
+++ b/libs/dtos/src/dtos/generics/credential.formatData.dto.ts
@@ -15,4 +15,16 @@ export class CredentialFormatDataDto {
   public anoncredsCredential?: AnonCredsCredential;
 
   public all?: unknown;
+
+  public static fromJson(json: InstanceType<typeof CredentialFormatDataDto>) {
+    const dto = new CredentialFormatDataDto();
+    dto.proposalAttributes = json.proposalAttributes;
+    dto.offerAttributes = json.offerAttributes;
+    dto.anoncredsProposal = json.anoncredsProposal;
+    dto.anoncredsOffer = json.anoncredsOffer;
+    dto.anoncredsRequest = json.anoncredsRequest;
+    dto.anoncredsCredential = json.anoncredsCredential;
+    dto.all = json.all;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/credential.record.dto.ts b/libs/dtos/src/dtos/generics/credential.record.dto.ts
index 97357d8d..b8582657 100644
--- a/libs/dtos/src/dtos/generics/credential.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/credential.record.dto.ts
@@ -7,11 +7,7 @@ import { CredentialState } from "@credo-ts/core";
 export class CredentialRecordDto extends BaseRecordDto {
   @IsNotEmpty()
   @IsString()
-  public state: CredentialState;
-
-  @IsNotEmpty()
-  @IsString()
-  credentialRecordType: string;
+  state: CredentialState;
 
   @IsString()
   connectionId?: string;
@@ -22,4 +18,18 @@ export class CredentialRecordDto extends BaseRecordDto {
   attributes?: Array<OfferCredentialAttributes>;
 
   tags: unknown;
+
+  public static override fromJson(
+    json: InstanceType<typeof CredentialRecordDto>,
+  ) {
+    const dto = new CredentialRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.state = json.state;
+    dto.connectionId = json.connectionId;
+    dto.attributes = json.attributes;
+    dto.tags = json.tags;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/did.record.dto.ts b/libs/dtos/src/dtos/generics/did.record.dto.ts
index d08551a6..e579f48d 100644
--- a/libs/dtos/src/dtos/generics/did.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/did.record.dto.ts
@@ -16,4 +16,16 @@ export class DidRecordDto extends BaseRecordDto {
   method: string;
 
   tags: unknown;
+
+  public static override fromJson(json: InstanceType<typeof DidRecordDto>) {
+    const dto = new DidRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.did = json.did;
+    dto.role = json.role;
+    dto.method = json.method;
+    dto.tags = json.tags;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/message.record.dto.ts b/libs/dtos/src/dtos/generics/message.record.dto.ts
index ece1fb57..93bdf3fd 100644
--- a/libs/dtos/src/dtos/generics/message.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/message.record.dto.ts
@@ -28,4 +28,18 @@ export class MessageRecordDto extends BaseRecordDto {
   @IsNotEmpty()
   @IsString()
   content: string;
+
+  public static override fromJson(json: InstanceType<typeof MessageRecordDto>) {
+    const dto = new MessageRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.connectionId = json.connectionId;
+    dto.role = json.role;
+    dto.sentTime = json.sentTime;
+    dto.from = json.from;
+    dto.to = json.to;
+    dto.content = json.content;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/proof.formatData.dto.ts b/libs/dtos/src/dtos/generics/proof.formatData.dto.ts
index fb0e74d3..021a8c6b 100644
--- a/libs/dtos/src/dtos/generics/proof.formatData.dto.ts
+++ b/libs/dtos/src/dtos/generics/proof.formatData.dto.ts
@@ -4,4 +4,12 @@ export class ProofFormatDataDto {
   public anoncredsProposal?: AnonCredsProofRequest;
   public anoncredsRequest?: AnonCredsProofRequest;
   public anoncredsPresentation?: AnonCredsProof;
+
+  public static fromJson(json: InstanceType<typeof ProofFormatDataDto>) {
+    const dto = new ProofFormatDataDto();
+    dto.anoncredsProposal = json.anoncredsProposal;
+    dto.anoncredsRequest = json.anoncredsRequest;
+    dto.anoncredsPresentation = json.anoncredsPresentation;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/proof.record.dto.ts b/libs/dtos/src/dtos/generics/proof.record.dto.ts
index cdc09da9..1f5773b1 100644
--- a/libs/dtos/src/dtos/generics/proof.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/proof.record.dto.ts
@@ -11,4 +11,15 @@ export class ProofRecordDto extends BaseRecordDto {
   state: ProofState;
 
   tags: unknown;
+
+  public static override fromJson(json: InstanceType<typeof ProofRecordDto>) {
+    const dto = new ProofRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.connectionId = json.connectionId;
+    dto.state = json.state;
+    dto.tags = json.tags;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/generics/schema.record.dto.ts b/libs/dtos/src/dtos/generics/schema.record.dto.ts
index 506b124b..8f8e732c 100644
--- a/libs/dtos/src/dtos/generics/schema.record.dto.ts
+++ b/libs/dtos/src/dtos/generics/schema.record.dto.ts
@@ -20,4 +20,17 @@ export class SchemaRecordDto extends BaseRecordDto {
 
   @IsString()
   methodName?: string;
+
+  public static override fromJson(json: InstanceType<typeof SchemaRecordDto>) {
+    const dto = new SchemaRecordDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.name = json.name;
+    dto.attributes = json.attributes;
+    dto.version = json.version;
+    dto.issuerId = json.issuerId;
+    dto.methodName = json.methodName;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/responses/create.invitation.response.dto.ts b/libs/dtos/src/dtos/responses/create.invitation.response.dto.ts
index 5fdda8e4..e586bdf7 100644
--- a/libs/dtos/src/dtos/responses/create.invitation.response.dto.ts
+++ b/libs/dtos/src/dtos/responses/create.invitation.response.dto.ts
@@ -42,4 +42,19 @@ export class CreateInvitationResponseDto extends BaseRecordDto {
   @IsOptional()
   @IsString()
   state?: OutOfBandState;
+
+  public static override fromJson(
+    json: InstanceType<typeof CreateInvitationResponseDto>,
+  ) {
+    const dto = new CreateInvitationResponseDto();
+    dto.id = json.id;
+    dto.createdAt = json.createdAt;
+    dto.updatedAt = json.updatedAt;
+    dto.invitationUrl = json.invitationUrl;
+    dto.shortInvitationUrl = json.shortInvitationUrl;
+    dto.outOfBandId = json.outOfBandId;
+    dto.role = json.role;
+    dto.state = json.state;
+    return dto;
+  }
 }
diff --git a/libs/dtos/src/dtos/responses/gateway.accepted.response.dto.ts b/libs/dtos/src/dtos/responses/gateway.accepted.response.dto.ts
index 535c4cb1..421d7da0 100644
--- a/libs/dtos/src/dtos/responses/gateway.accepted.response.dto.ts
+++ b/libs/dtos/src/dtos/responses/gateway.accepted.response.dto.ts
@@ -5,4 +5,12 @@ export class GatewayAcceptedResponseDto {
   //@description test mest
   @IsUUID()
   id: string;
+
+  public static fromJson(
+    json: InstanceType<typeof GatewayAcceptedResponseDto>,
+  ) {
+    const dto = new GatewayAcceptedResponseDto();
+    dto.id = json.id;
+    return dto;
+  }
 }
-- 
GitLab