diff --git a/.env.example b/.env.example
index 5434e09a6c663550d900224de4d37d61fa66a33f..c3cd2caa3094daa00407959cfc222e7e39e601c5 100644
--- a/.env.example
+++ b/.env.example
@@ -1,5 +1,7 @@
 LEDGERS="BCOVRIN_TEST"
 IDUNION_KEY=#add if you are using IDUNION as a ledger
+IDUNION_BASIC_USER=#add if you are using IDUNION as a ledger
+IDUNION_BASIC_PASS=#add if you are using IDUNION as a ledger
 
 AGENT_PEER_URL="http://localhost:8001"
 AGENT_NAME=EXAMPTTLE_AGENT_45
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d7649651c9c71e7702074b41361e0f740060cd4c..e3a15b48b38ffa0e006f839098acdf1144c9a9ad 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,13 @@
 All notable changes to this project will be documented in this file. See
 [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
 
+## [1.8.0](https://code.vereign.com/gaiax/ocm/ocm-engine/compare/v1.7.1...v1.8.0) (2023-09-12)
+
+
+### Features
+
+* rest agent support for connection and proof change state events ([de04959](https://code.vereign.com/gaiax/ocm/ocm-engine/commit/de04959d975f398fd5ab4ce628fba57a440c9d0b))
+
 ## [1.7.1](https://code.vereign.com/gaiax/ocm/ocm-engine/compare/v1.7.0...v1.7.1) (2023-08-21)
 
 
diff --git a/apps/gateway/src/app/managers/attestation.controller.ts b/apps/gateway/src/app/managers/attestation.controller.ts
index 88140a189570219c7d9f3fa5af5614d19f701ee5..536fc82cb7564ea2e17f888c4dcf3bd3ddc9d6b8 100644
--- a/apps/gateway/src/app/managers/attestation.controller.ts
+++ b/apps/gateway/src/app/managers/attestation.controller.ts
@@ -1,12 +1,4 @@
-import {
-  BadRequestException,
-  Body,
-  Controller,
-  Get,
-  Param,
-  Post,
-  UseFilters,
-} from "@nestjs/common";
+import { Body, Controller, Get, Param, Post, UseFilters } from "@nestjs/common";
 import { AllExceptionsHandler } from "../exception.handler";
 import { AttestationManagerClient } from "@ocm-engine/clients";
 import {
diff --git a/apps/gateway/src/app/managers/proof.controller.ts b/apps/gateway/src/app/managers/proof.controller.ts
index f3df78b61f836c0c63964f9acbefff6c23c86a83..210181d9706c8ac7b900ab42da2eb357dfc52944 100644
--- a/apps/gateway/src/app/managers/proof.controller.ts
+++ b/apps/gateway/src/app/managers/proof.controller.ts
@@ -1,12 +1,4 @@
-import {
-  BadRequestException,
-  Body,
-  Controller,
-  Get,
-  Param,
-  Post,
-  UseFilters,
-} from "@nestjs/common";
+import { Body, Controller, Get, Param, Post, UseFilters } from "@nestjs/common";
 import {
   AcceptProofRequestDto,
   DeclineProofRequestDto,
@@ -80,7 +72,6 @@ export class ProofController {
     });
   }
 
-
   @Get("/credentials/proof/:proof_record_id")
   @ApiResponse({
     status: 200,
@@ -204,7 +195,7 @@ export class ProofController {
     });
   }
 
-  @Post(`/credentials/proof/:proof_record_id/accept`)
+  @Post(`/credentials/proof/accept`)
   @ApiResponse({
     status: 201,
     description:
@@ -239,15 +230,12 @@ export class ProofController {
       "Method accept credential proof. The id of the response will be matched when you receive event from the websocket",
     tags: ["Credentials Proof"],
   })
-  acceptProof(@Param("proof_record_id") proofRecordId: string) {
-    const data = new AcceptProofRequestDto();
-    data.proofRecordId = proofRecordId;
-
+  acceptProof(@Body() acceptProofRequestDto: AcceptProofRequestDto) {
     return this.pmClient.sendPayload<AcceptProofRequestDto>({
       pattern: "proofs",
       payload: {
-        source: "/credentials/proofs/:id/accept",
-        data,
+        source: "/credentials/proofs/accept",
+        data: acceptProofRequestDto,
         type: PROOF_ACCEPT,
       },
     });
diff --git a/apps/proof-manager/src/app/app.controller.ts b/apps/proof-manager/src/app/app.controller.ts
index b7e41ea0dda88da0b3225d4bdacb1ba6b9af0f2c..8f80bb48ed6abd241e156069437b38519f8e79a9 100644
--- a/apps/proof-manager/src/app/app.controller.ts
+++ b/apps/proof-manager/src/app/app.controller.ts
@@ -3,6 +3,7 @@ import { Body, Controller, Logger } from "@nestjs/common";
 import { ProducerService } from "@ocm-engine/nats";
 import { MessagePattern, RpcException } from "@nestjs/microservices";
 import {
+  AcceptProofRequestDto,
   CloudEventDto,
   GatewayAcceptedResponseDto,
   makeEvent,
@@ -19,7 +20,7 @@ export class AppController {
   async create(
     @Body()
     payload: {
-      data: null;
+      data: null | AcceptProofRequestDto;
       type: ProofEvent;
       source: string;
     },
diff --git a/compose/docker-compose.simple.yml b/compose/docker-compose.simple.yml
index 30d614e481ab7e208ea86f184cf39f4fe029c862..5508f648a5d3d4fa4f0c5e372b7387fd57e73fae 100644
--- a/compose/docker-compose.simple.yml
+++ b/compose/docker-compose.simple.yml
@@ -1,6 +1,30 @@
 version: '3.8'
 
 services:
+
+  builder:
+    privileged: true
+    image: node:18.16.0-buster-slim
+    volumes:
+      - ./../yarn.lock:/app/yarn.lock
+      - ./../package.json:/app/package.json
+      - ./../apps:/app/apps
+      - ./../libs:/app/libs
+      - ./../nx.json:/app/nx.json
+      - ./../tsconfig.base.json:/app/tsconfig.base.json
+      - ./data/node_modules:/app/node_modules
+      - ./data/dist:/app/dist
+    working_dir: /app
+    command:
+      - sh
+      - -c
+      - |
+        whoami
+        apt update -y && apt install python3 git make build-essential -y
+        yarn install
+        yarn build:agent
+        exit 0
+
   pg_db:
     image: 'postgres:latest'
     ports:
@@ -12,10 +36,13 @@ services:
       - ./data/db-simple/:/var/lib/postgresql/data/
 
   agent-issuer-simple:
+    image: node:18.16.0
+    volumes:
+      - ./data/node_modules:/app/node_modules
+      - ./data/dist/apps/agent:/app/
+    working_dir: /app
+    command: node main.js
     container_name: agent-issuer-simple
-    build:
-      context: "../"
-      dockerfile: "./apps/agent/deployment/local/Dockerfile"
     env_file:
       - ./env/issuer.simple.env
     ports:
@@ -24,12 +51,17 @@ services:
     depends_on:
       pg_db:
         condition: service_started
+      builder:
+        condition: service_completed_successfully
 
   agent-holder-simple:
     container_name: agent-holder-simple
-    build:
-      context: "../"
-      dockerfile: "./apps/agent/deployment/local/Dockerfile"
+    image: node:18.16.0
+    volumes:
+      - ./data/node_modules:/app/node_modules
+      - ./data/dist/apps/agent:/app/
+    working_dir: /app
+    command: node main.js
     env_file:
       - ./env/holder.simple.env
     ports:
@@ -38,3 +70,6 @@ services:
     depends_on:
       pg_db:
         condition: service_started
+      builder:
+        condition: service_completed_successfully
+
diff --git a/compose/env/holder.simple.env b/compose/env/holder.simple.env
index 8928d0564da69e5b9af00c27a7c8cd4e6f2f1086..6fb198c52bab9de6d815468f737c1e3c5abfdc5d 100644
--- a/compose/env/holder.simple.env
+++ b/compose/env/holder.simple.env
@@ -1,14 +1,18 @@
 LEDGERS="BCOVRIN_TEST"
+
 IDUNION_KEY=
+IDUNION_BASIC_USER=
+IDUNION_BASIC_PASS=
 
-AGENT_PEER_URL="http://agent-holder:6001"
-AGENT_NAME=DEV_SIMPLE_AGENT_HOLDER_OCM # this should be changed to company name
-AGENT_KEY=DEV_SIMPLE_AGENT_HOLDER_OCM #example random string
-AGENT_DID_SEED=200000000000000000000000TCuste21xh #did private key seed min lenght 32
+AGENT_PEER_URL=http://agent-holder-simple:6001
+AGENT_PEER_PORT=6001
+AGENT_NAME=DEV_SIMPLE_AGENT_HOLDER_OCM_3919 # this should be changed to company name
+AGENT_KEY=DEV_SIMPLE_AGENT_HOLDER_OCM_3818 #example random string
+AGENT_DID_SEED=jhPctchKaUfyZ1ioz6Fjypoasdhjahjsiscdkd23ozxflxkaKD0RR4TICwx
 AGENT_DB_HOST=pg_db:5432
 AGENT_DB_USER=postgres
 AGENT_DB_PASS=postgres
-AGENT_PORT=8081
+AGENT_PORT=8080
 AGENT_CONSUMER_NAME=agent_1
 AGENT_IS_REST=true
 AGENT_MAX_MESSAGES=10
diff --git a/compose/env/issuer.simple.env b/compose/env/issuer.simple.env
index 465996055c663cc68da01f3dd997f54f61404aa9..86e1d2bfc69f5b3d6a3309f5adb9f7278ecb31ac 100644
--- a/compose/env/issuer.simple.env
+++ b/compose/env/issuer.simple.env
@@ -1,14 +1,18 @@
 LEDGERS="BCOVRIN_TEST"
-IDUNION_KEY=
 
-AGENT_PEER_URL="http://agent-issuer:8001"
-AGENT_NAME=DEV_SIMPLE_AGENT_ISSUER_OCM # this should be changed to company name
-AGENT_KEY=DEV_SIMPLE_AGENT_ISSUER_OCM #example random string
-AGENT_DID_SEED=200000000000000000000000TCuste21js #did private key seed min lenght 32
+IDUNION_KEY=6eb8859f-dd7f-445a-bc37-ba986145d3b6
+IDUNION_BASIC_USER=idunion4ssi
+IDUNION_BASIC_PASS=7eDZ+LrUbV5bCRwe6Ki0Gw==
+
+AGENT_PEER_URL=http://agent-issuer-simple:8001
+AGENT_PEER_PORT=8001
+AGENT_NAME=DEV_SIMPLE_AGENT_ISSUER_OCM_45 # this should be changed to company name
+AGENT_KEY=DEV_SIMPLE_AGENT_ISSUER_OCM_45 #example random string
+AGENT_DID_SEED=Cd0VanW68R3HCaskjdakjsNpiuadscmsBBPP3DV6pMdwDFdHvPasdasdas
 AGENT_DB_HOST=pg_db:5432
 AGENT_DB_USER=postgres
 AGENT_DB_PASS=postgres
-AGENT_PORT=8081
+AGENT_PORT=8080
 AGENT_CONSUMER_NAME=agent_1
 AGENT_IS_REST=true
 AGENT_MAX_MESSAGES=10
diff --git a/gateway-swagger.json b/gateway-swagger.json
index 0da4211542ced768ce3d3628b3b896e7011415af..0bf822f3adb58256d8fdca9f0b1d85a79f33c4a6 100644
--- a/gateway-swagger.json
+++ b/gateway-swagger.json
@@ -1 +1 @@
-{"openapi":"3.0.0","paths":{"/api/v1/invitations":{"post":{"operationId":"ConnectionController_createInvitation","summary":"Create invitation for connection","description":"Method will create invitation url. The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[],"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/invitations/accept":{"post":{"operationId":"ConnectionController_acceptInvitation","summary":"Accept invitation for connection","description":"Method will accept the invitation and will return connection thought the websocket. The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvitationResponseDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["invitationUrl must be a string","invitationUrl should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/connections":{"get":{"operationId":"ConnectionController_list","summary":"List all connections","description":"The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/connections/{id}":{"get":{"operationId":"ConnectionController_getById","summary":"Get connection by id","description":"The method will search for connection id, if not found null will be returned. The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/schemas":{"post":{"operationId":"AttestationController_createSchema","summary":"Create schema","description":"Method will create schema. The id of the response will be matched when you receive event from the websocket","tags":["Schema"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSchemaRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["name must be a string","name should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}},"get":{"operationId":"AttestationController_listSchema","summary":"List all schemas","description":"Method will fetch all schemas. The id of the response will be matched when you receive event from the websocket","tags":["Schema"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/schemas-by-id":{"post":{"operationId":"AttestationController_getSchemaById","summary":"Get schema by id","description":"Method will fetch specific schema or return null. The id of the response will be matched when you receive event from the websocket","tags":["Schema"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSchemaRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["schemaId must be a string","schemaId should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/definition":{"post":{"operationId":"AttestationController_createCredentialDefinition","summary":"Create credential definition","description":"Method create credential definition. The id of the response will be matched when you receive event from the websocket","tags":["Credentials"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCredentialDefinitionRequsetDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["schemaId must be a string","schemaId should not be empty","tag must be a string","tag should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/issue":{"post":{"operationId":"AttestationController_issueCredential","summary":"Issue credential","description":"Method issue credential, it will create an offer and send it to specified receiver (connectionId). The id of the response will be matched when you receive event from the websocket","tags":["Credentials"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueCredentialRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["connectionId must be a string","connectionId should not be empty","credentialDefinitionId must be a string","credentialDefinitionId should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials":{"get":{"operationId":"AttestationController_credentials","summary":"List all credential","description":"Method list credential definition no filters applied. The id of the response will be matched when you receive event from the websocket","tags":["Credentials"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/offers":{"get":{"operationId":"AttestationController_getCredentialOffers","summary":"List unaccepted credential offers","description":"Method list offers that are received, but not accepted. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Offers"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/offers/{credential_record_id}/accept":{"post":{"operationId":"AttestationController_acceptCredential","summary":"Accept credential offers","description":"Method list accept credential offer. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Offers"],"parameters":[{"name":"credential_record_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"201":{"description":""},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/messages":{"post":{"operationId":"AttestationController_sendMeesage","summary":"Send basic message","description":"Method will send basic message to a connection. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Offers"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MakeBasicMessageRequestDto"}}}},"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"201":{"description":""},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["connectionId must be a string","connectionId should not be empty","message must be a string","message should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/proof":{"get":{"operationId":"ProofController_proofs","summary":"List received unaccepted proofs","description":"Method list all received unaccepted proofs. Status - request-receive. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}},"/api/v1/credentials/proof/issue":{"post":{"operationId":"ProofController_issueProof","summary":"Issue proof for credential","description":"Method will issue proof. If connection id is not passed, the proof will be OOB. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueProofRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["attributes must contain at least 1 elements","attributes must be an array"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}},"/api/v1/credentials/proof/{proof_record_id}/accept":{"post":{"operationId":"ProofController_acceptProof","summary":"Accept credential proof","description":"Method accept credential proof. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof"],"parameters":[{"name":"proof_record_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}}},"info":{"title":"OCM Gateway","description":"OCM ENGINE GATEWAY API","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"http://0.0.0.0:8081"}],"components":{"schemas":{"CloudEventDto":{"type":"object","properties":{}},"GatewayAcceptedResponseDto":{"type":"object","properties":{"id":{"type":"string","example":"80633e6d-c606-4539-a3df-287fedd09253"}},"required":["id"]},"CreateInvitationResponseDto":{"type":"object","properties":{"invitationUrl":{"type":"string","description":"A list of user's roles","example":"http://0.0.0.0:8001?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIzYWExNGIzNC04YTk5LTQxY2UtYTY3NC1jODUxYmVhMTIxMWEiLCJsYWJlbCI6IkRFeGNWYXNkX0FHRU5UXzQ1IiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly8wLjAuMC4wOjgwMDEiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa3VFcHllc1pNa3k0a1BpQzhEOEplZERlcm55YTFuaTREMUF3ZmdnWWt6YmR4Il0sInJvdXRpbmdLZXlzIjpbXX1dfQ"}},"required":["invitationUrl"]},"CreateSchemaRequestDto":{"type":"object","properties":{"name":{"type":"string","example":"my test schema"},"attributes":{"example":["first_name, last_name"],"type":"array","items":{"type":"string"}},"version":{"type":"string","example":"1.0.2","pattern":"/^(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)$/"}},"required":["name","attributes","version"]},"GetSchemaRequestDto":{"type":"object","properties":{"schemaId":{"type":"string","example":"did:indy:LEDNGER:SXM76gQwRnjkgoz2oBnGjd/anoncreds/v0/SCHEMA/test schema/1.0.2"}},"required":["schemaId"]},"CreateCredentialDefinitionRequsetDto":{"type":"object","properties":{"schemaId":{"type":"string"},"tag":{"type":"string"}},"required":["schemaId","tag"]},"IssueCredentialAttributes":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"IssueCredentialRequestDto":{"type":"object","properties":{"connectionId":{"type":"string","example":"6464b521-005a-4379-91e0-a3692b31cafd"},"credentialDefinitionId":{"type":"string"},"attributes":{"type":"array","items":{"$ref":"#/components/schemas/IssueCredentialAttributes"}}},"required":["connectionId","credentialDefinitionId","attributes"]},"MakeBasicMessageRequestDto":{"type":"object","properties":{"connectionId":{"type":"string","example":"6464b521-005a-4379-91e0-a3692b31cafd"},"message":{"type":"string","example":"hello world"}},"required":["connectionId","message"]},"IssueProofAttribute":{"type":"object","properties":{"attributeName":{"type":"string"},"credentialDefinitionId":{"type":"string"},"schemaId":{"type":"string"}},"required":["attributeName","credentialDefinitionId","schemaId"]},"IssueProofRequestDto":{"type":"object","properties":{"connectionId":{"type":"string","example":"6464b521-005a-4379-91e0-a3692b31cafd"},"attributes":{"type":"array","items":{"$ref":"#/components/schemas/IssueProofAttribute"}}},"required":["attributes"]}}}}
\ No newline at end of file
+{"openapi":"3.0.0","paths":{"/api/v1/invitations":{"post":{"operationId":"ConnectionController_createInvitation","summary":"Create invitation for connection","description":"Method will create invitation url. The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[],"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/invitations/accept":{"post":{"operationId":"ConnectionController_acceptInvitation","summary":"Accept invitation for connection","description":"Method will accept the invitation and will return connection thought the websocket. The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvitationResponseDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["invitationUrl must be a string","invitationUrl should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/connections":{"get":{"operationId":"ConnectionController_list","summary":"List all connections","description":"The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/connections/{id}":{"get":{"operationId":"ConnectionController_getById","summary":"Get connection by id","description":"The method will search for connection id, if not found null will be returned. The id of the response will be matched when you receive event from the websocket","tags":["Connections"],"parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to connection manager. This error shows that connection manager could not convert request to event or connection manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:4312"}}}}}}}}},"/api/v1/schemas":{"post":{"operationId":"AttestationController_createSchema","summary":"Create schema","description":"Method will create schema. The id of the response will be matched when you receive event from the websocket","tags":["Schema"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSchemaRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["name must be a string","name should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}},"get":{"operationId":"AttestationController_listSchema","summary":"List all schemas","description":"Method will fetch all schemas. The id of the response will be matched when you receive event from the websocket","tags":["Schema"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/schemas-by-id":{"post":{"operationId":"AttestationController_getSchemaById","summary":"Get schema by id","description":"Method will fetch specific schema or return null. The id of the response will be matched when you receive event from the websocket","tags":["Schema"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSchemaRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["schemaId must be a string","schemaId should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/definition":{"post":{"operationId":"AttestationController_createCredentialDefinition","summary":"Create credential definition","description":"Method create credential definition. The id of the response will be matched when you receive event from the websocket","tags":["Credentials"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCredentialDefinitionRequsetDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["schemaId must be a string","schemaId should not be empty","tag must be a string","tag should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/issue":{"post":{"operationId":"AttestationController_issueCredential","summary":"Issue credential","description":"Method issue credential, it will create an offer and send it to specified receiver (connectionId). The id of the response will be matched when you receive event from the websocket","tags":["Credentials"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueCredentialRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["connectionId must be a string","connectionId should not be empty","credentialDefinitionId must be a string","credentialDefinitionId should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials":{"get":{"operationId":"AttestationController_credentials","summary":"List all credential","description":"Method list credential definition no filters applied. The id of the response will be matched when you receive event from the websocket","tags":["Credentials"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/offers":{"get":{"operationId":"AttestationController_getCredentialOffers","summary":"List unaccepted credential offers","description":"Method list offers that are received, but not accepted. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Offers"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/offers/{credential_record_id}/accept":{"post":{"operationId":"AttestationController_acceptCredential","summary":"Accept credential offers","description":"Method list accept credential offer. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Offers"],"parameters":[{"name":"credential_record_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"201":{"description":""},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/messages":{"post":{"operationId":"AttestationController_sendMeesage","summary":"Send basic message","description":"Method will send basic message to a connection. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Offers"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MakeBasicMessageRequestDto"}}}},"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"201":{"description":""},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["connectionId must be a string","connectionId should not be empty","message must be a string","message should not be empty"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to attestation manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1234"}}}}}}}}},"/api/v1/credentials/proof":{"get":{"operationId":"ProofController_proofs","summary":"List received unaccepted proofs","description":"Method list all received unaccepted proofs. Status - request-receive. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof"],"parameters":[],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}},"/api/v1/credentials/proof/{proof_record_id}":{"get":{"operationId":"ProofController_getProofById","summary":"Get a single proof record by providing proof record id.","description":"Method get proof by id. Status - request-receive. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof Get Id"],"parameters":[{"name":"proof_record_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}},"/api/v1/credentials/proof/issue":{"post":{"operationId":"ProofController_issueProof","summary":"Issue proof for credential","description":"Method will issue proof. If connection id is not passed, the proof will be OOB. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueProofRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"message":{"type":"array","example":["attributes must contain at least 1 elements","attributes must be an array"]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}},"/api/v1/credentials/proof/accept":{"post":{"operationId":"ProofController_acceptProof","summary":"Accept credential proof","description":"Method accept credential proof. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptProofRequestDto"}}}},"responses":{"201":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}},"/api/v1/credentials/proof/{proof_record_id}/decline":{"post":{"operationId":"ProofController_declineProofRequest","summary":"Decline a proof request.","description":"Method to decline a proof request by id. Status - request-receive. The id of the response will be matched when you receive event from the websocket","tags":["Credentials Proof Decline Request Id"],"parameters":[{"name":"proof_record_id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Request is accepted for execution, the response id will match the event id received from the web socket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GatewayAcceptedResponseDto"}}}},"201":{"description":""},"500":{"description":"Error in sending data to proof manager. This error shows that proof manager could not convert request to event or proof manager could not send the event to the broker.","content":{"application/json":{"schema":{"type":"object","properties":{"statusCode":{"type":"number","example":500},"message":{"type":"string","example":"connect ECONNREFUSED 0.0.0.0.0:1919"}}}}}}}}}},"info":{"title":"OCM Gateway","description":"OCM ENGINE GATEWAY API","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"http://undefined:NaN"}],"components":{"schemas":{"CloudEventDto":{"type":"object","properties":{}},"GatewayAcceptedResponseDto":{"type":"object","properties":{"id":{"type":"string","example":"80633e6d-c606-4539-a3df-287fedd09253"}},"required":["id"]},"CreateInvitationResponseDto":{"type":"object","properties":{"invitationUrl":{"type":"string","description":"A list of user's roles","example":"http://0.0.0.0:8001?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIzYWExNGIzNC04YTk5LTQxY2UtYTY3NC1jODUxYmVhMTIxMWEiLCJsYWJlbCI6IkRFeGNWYXNkX0FHRU5UXzQ1IiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly8wLjAuMC4wOjgwMDEiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa3VFcHllc1pNa3k0a1BpQzhEOEplZERlcm55YTFuaTREMUF3ZmdnWWt6YmR4Il0sInJvdXRpbmdLZXlzIjpbXX1dfQ"}},"required":["invitationUrl"]},"CreateSchemaRequestDto":{"type":"object","properties":{"name":{"type":"string","example":"my test schema"},"attributes":{"example":["first_name, last_name"],"type":"array","items":{"type":"string"}},"version":{"type":"string","example":"1.0.2","pattern":"/^(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)$/"}},"required":["name","attributes","version"]},"GetSchemaRequestDto":{"type":"object","properties":{"schemaId":{"type":"string","example":"did:indy:LEDNGER:SXM76gQwRnjkgoz2oBnGjd/anoncreds/v0/SCHEMA/test schema/1.0.2"}},"required":["schemaId"]},"CreateCredentialDefinitionRequsetDto":{"type":"object","properties":{"schemaId":{"type":"string"},"tag":{"type":"string"}},"required":["schemaId","tag"]},"IssueCredentialAttributes":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"IssueCredentialRequestDto":{"type":"object","properties":{"connectionId":{"type":"string","example":"6464b521-005a-4379-91e0-a3692b31cafd"},"credentialDefinitionId":{"type":"string"},"attributes":{"type":"array","items":{"$ref":"#/components/schemas/IssueCredentialAttributes"}}},"required":["connectionId","credentialDefinitionId","attributes"]},"MakeBasicMessageRequestDto":{"type":"object","properties":{"connectionId":{"type":"string","example":"6464b521-005a-4379-91e0-a3692b31cafd"},"message":{"type":"string","example":"hello world"}},"required":["connectionId","message"]},"IssueProofAttribute":{"type":"object","properties":{"attributeName":{"type":"string"},"credentialDefinitionId":{"type":"string"},"schemaId":{"type":"string"}},"required":["attributeName","credentialDefinitionId","schemaId"]},"IssueProofRequestDto":{"type":"object","properties":{"connectionId":{"type":"string","example":"6464b521-005a-4379-91e0-a3692b31cafd"},"attributes":{"type":"array","items":{"$ref":"#/components/schemas/IssueProofAttribute"}}},"required":["attributes"]},"AcceptProofRequestDto":{"type":"object","properties":{"proofRecordId":{"type":"string"},"proofUrl":{"type":"string"}},"required":["proofRecordId","proofUrl"]}}}}
\ No newline at end of file
diff --git a/libs/askar/src/agent.utils.ts b/libs/askar/src/agent.utils.ts
index 3eae5e959a039310952d4bdaadd5e631d6e54827..9bca784c0838eac47a45b12ac1ca83e3b0f23673 100644
--- a/libs/askar/src/agent.utils.ts
+++ b/libs/askar/src/agent.utils.ts
@@ -2,12 +2,21 @@ import {
   Agent,
   AutoAcceptCredential,
   AutoAcceptProof,
+  BaseEvent,
   ConnectionsModule,
+  ConnectionStateChangedEvent,
   CredentialsModule,
+  DidExchangeRole,
   DidsModule,
+  EncryptedMessage,
   Key,
+  KeyDidResolver,
   KeyType,
+  PeerDidResolver,
+  ProofEventTypes,
   ProofsModule,
+  ProofState,
+  ProofStateChangedEvent,
   TypedArrayEncoder,
   V2CredentialProtocol,
   V2ProofProtocol,
@@ -17,6 +26,7 @@ import {
 import {
   AnonCredsCredentialFormatService,
   AnonCredsModule,
+  AnonCredsProof,
   AnonCredsProofFormatService,
 } from "@aries-framework/anoncreds";
 import {
@@ -31,6 +41,27 @@ import { indyVdr } from "@hyperledger/indy-vdr-nodejs";
 import { AskarModule } from "@aries-framework/askar";
 import { ariesAskar } from "@hyperledger/aries-askar-nodejs";
 import { Key as C, KeyAlgs } from "@hyperledger/aries-askar-shared";
+import { IConfAgent } from "@ocm-engine/config";
+import axios from "axios";
+import {
+  catchError,
+  filter,
+  lastValueFrom,
+  map,
+  Observable,
+  ReplaySubject,
+  Subject,
+  take,
+  timeout,
+} from "rxjs";
+import { SubjectInboundTransport } from "./askar/transports/agent.subject.inbound.transport";
+import { SubjectOutboundTransport } from "./askar/transports/agent.subject.outbound.transport";
+
+export type EventReplaySubject = ReplaySubject<BaseEvent>;
+export type SubjectMessage = {
+  message: EncryptedMessage;
+  replySubject?: Subject<SubjectMessage>;
+};
 
 export const importDidsToWallet = async (
   agent: Agent,
@@ -126,10 +157,231 @@ export const getAskarAnonCredsIndyModules = (networks: any) => {
     }),
     dids: new DidsModule({
       registrars: [new IndyVdrIndyDidRegistrar()],
-      resolvers: [new IndyVdrIndyDidResolver()],
+      resolvers: [
+        new IndyVdrIndyDidResolver(),
+        new KeyDidResolver(),
+        new PeerDidResolver(),
+      ],
     }),
     askar: new AskarModule({
       ariesAskar,
     }),
   } as const;
 };
+
+export const setupEventReplaySubjects = (
+  agents: Agent[],
+  eventTypes: string[],
+): ReplaySubject<BaseEvent>[] => {
+  const replaySubjects: EventReplaySubject[] = [];
+
+  for (const agent of agents) {
+    const replaySubject = new ReplaySubject<BaseEvent>();
+
+    for (const eventType of eventTypes) {
+      agent.events.observable(eventType).subscribe(replaySubject);
+    }
+
+    replaySubjects.push(replaySubject);
+  }
+
+  return replaySubjects;
+};
+
+export const setupSubjectTransports = (agents: Agent[]) => {
+  const subjectMap: Record<string, Subject<SubjectMessage>> = {};
+
+  for (const agent of agents) {
+    const messages = new Subject<SubjectMessage>();
+    subjectMap[agent.config.endpoints[0]] = messages;
+    agent.registerInboundTransport(new SubjectInboundTransport(messages));
+    agent.registerOutboundTransport(new SubjectOutboundTransport(subjectMap));
+  }
+};
+
+export const svdxProofStateChangeHandler = async (
+  ev: ProofStateChangedEvent,
+  agent: Agent,
+  config?: IConfAgent,
+) => {
+  if (ProofState.Done !== ev.payload.proofRecord.state) {
+    return;
+  }
+
+  const presentationMessage = await agent.proofs.findPresentationMessage(
+    ev.payload.proofRecord.id,
+  );
+
+  console.log(JSON.stringify(presentationMessage, null, 2));
+  if (!presentationMessage) {
+    console.log("No presentation message found");
+    return;
+  }
+
+  const attachmentId = presentationMessage.formats[0].attachmentId;
+
+  const attachment =
+    presentationMessage.getPresentationAttachmentById(attachmentId);
+
+  console.log(JSON.stringify(attachment, null, 2));
+  if (!attachment) {
+    console.log("No attachment found");
+    return;
+  }
+
+  const email =
+    attachment.getDataAsJson<AnonCredsProof>()?.requested_proof.revealed_attrs[
+      "email"
+    ].raw;
+
+  if (!config?.agentSVDXWebHook) {
+    console.log("Agent SVDX web hook not set");
+    return;
+  }
+
+  try {
+    await axios.post(
+      config?.agentSVDXWebHook,
+      {
+        email,
+        connectionId: ev.payload.proofRecord.connectionId,
+      },
+      {
+        auth: {
+          username: config?.agentSVDXBasicUser,
+          password: config?.agentSVDXBasicPass,
+        },
+      },
+    );
+  } catch (e) {
+    console.log(JSON.stringify(e, null, 2));
+  }
+};
+
+export const svdxConnectionStateChangeHandler = async (
+  ev: ConnectionStateChangedEvent,
+  agent: Agent,
+  config?: IConfAgent,
+) => {
+  if (
+    ev.payload.connectionRecord.role === DidExchangeRole.Responder &&
+    ev.payload.connectionRecord.state !== "completed"
+  ) {
+    return;
+  }
+
+  await agent.connections.addConnectionType(
+    ev.payload.connectionRecord.id,
+    ev.payload.connectionRecord.theirLabel || "svdx",
+  );
+
+  console.log("connection accepted", JSON.stringify(ev, null, 2));
+
+  const connections = await agent.connections.findAllByConnectionTypes([
+    ev.payload.connectionRecord.theirLabel || "svdx",
+  ]);
+
+  if (connections.length < 2) {
+    return;
+  }
+
+  connections.sort(
+    (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(),
+  );
+
+  while (connections.length > 1) {
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const con = connections.pop()!;
+
+    console.log(`deleting ${con.id}`);
+    await agent.connections.deleteById(con.id);
+  }
+
+  try {
+    await agent.proofs.requestProof({
+      protocolVersion: "v2",
+      connectionId: connections[0].id,
+      proofFormats: {
+        anoncreds: {
+          name: "proof-request",
+          version: "1.0",
+          requested_attributes: {
+            email: {
+              name: "email",
+              restrictions: [
+                {
+                  schema_id: config?.agentSVDXSchemaId,
+                  cred_def_id: config?.agentSVDXCredDefId,
+                },
+              ],
+            },
+          },
+        },
+      },
+    });
+  } catch (e) {
+    console.log(JSON.stringify(e, null, 2));
+    console.log("failed to issue credential");
+  }
+};
+
+export const isProofStateChangedEvent = (
+  e: BaseEvent,
+): e is ProofStateChangedEvent => e.type === ProofEventTypes.ProofStateChanged;
+
+export const waitForProofExchangeRecordSubject = (
+  subject: ReplaySubject<BaseEvent> | Observable<BaseEvent>,
+  {
+    threadId,
+    parentThreadId,
+    state,
+    previousState,
+    timeoutMs = 10000,
+    count = 1,
+  }: {
+    threadId?: string;
+    parentThreadId?: string;
+    state?: ProofState;
+    previousState?: ProofState | null;
+    timeoutMs?: number;
+    count?: number;
+  },
+) => {
+  const observable: Observable<BaseEvent> =
+    subject instanceof ReplaySubject ? subject.asObservable() : subject;
+  return lastValueFrom(
+    observable.pipe(
+      filter(isProofStateChangedEvent),
+      filter(
+        (e) =>
+          previousState === undefined ||
+          e.payload.previousState === previousState,
+      ),
+      filter(
+        (e) =>
+          threadId === undefined || e.payload.proofRecord.threadId === threadId,
+      ),
+      filter(
+        (e) =>
+          parentThreadId === undefined ||
+          e.payload.proofRecord.parentThreadId === parentThreadId,
+      ),
+      filter(
+        (e) => state === undefined || e.payload.proofRecord.state === state,
+      ),
+      timeout(timeoutMs),
+      catchError(() => {
+        throw new Error(
+          `ProofStateChangedEvent event not emitted within specified timeout: ${timeoutMs}
+          previousState: ${previousState},
+          threadId: ${threadId},
+          parentThreadId: ${parentThreadId},
+          state: ${state}
+        }`,
+        );
+      }),
+      take(count),
+      map((e) => e.payload.proofRecord),
+    ),
+  );
+};
diff --git a/libs/askar/src/askar-nats/event.handler.service.ts b/libs/askar/src/askar-nats/event.handler.service.ts
index b384d7660f5980c8dd8e137135a1cb05896f6cb5..2738c57c4f2d7a32c01c7a6c3f2e5f9ffcfe2c46 100644
--- a/libs/askar/src/askar-nats/event.handler.service.ts
+++ b/libs/askar/src/askar-nats/event.handler.service.ts
@@ -118,8 +118,14 @@ export class EventHandlerService {
             break;
 
           case PROOF_ACCEPT:
-            dto = event.data as AcceptProofRequestDto;
-            data = await this.agentService.acceptProof(dto.proofRecordId);
+            data = await this.agentService.acceptProof(
+              event.data as AcceptProofRequestDto,
+            );
+            break;
+
+          case PROOF_DECLINE:
+            dto = event.data as DeclineProofRequestDto;
+            data = await this.agentService.declineProofRequest(dto.proofRecordId);
             break;
 
           case PROOF_DECLINE:
diff --git a/libs/askar/src/askar-rest/askar.rest.module.ts b/libs/askar/src/askar-rest/askar.rest.module.ts
index 7390822ad25c59d12e428ba08264ddc9bd9cee82..6aff9fe7d2977452b6a685ddcba21a21537042e1 100644
--- a/libs/askar/src/askar-rest/askar.rest.module.ts
+++ b/libs/askar/src/askar-rest/askar.rest.module.ts
@@ -1,12 +1,20 @@
-import { Module, ValidationPipe } from "@nestjs/common";
+import {
+  Module,
+  ValidationPipe,
+  MiddlewareConsumer,
+  RequestMethod,
+} from "@nestjs/common";
 import { AgentService } from "../askar/agent.service";
-import { ConfigModule } from "@nestjs/config";
+import { ConfigModule, ConfigService } from "@nestjs/config";
 import { LedgersModule } from "@ocm-engine/ledgers";
 import { APP_PIPE } from "@nestjs/core";
 import { RestController } from "./rest.controller";
+import { PassportModule } from "@nestjs/passport";
+import { BasicAuthMiddleware } from "./auth/basic.middleware";
+import { IConfAgent } from "@ocm-engine/config";
 
 @Module({
-  imports: [ConfigModule, LedgersModule],
+  imports: [ConfigModule, LedgersModule, PassportModule],
   providers: [
     AgentService,
     {
@@ -18,4 +26,17 @@ import { RestController } from "./rest.controller";
   ],
   controllers: [RestController],
 })
-export class AskarRestModule {}
+export class AskarRestModule {
+  constructor(private readonly configService: ConfigService) {}
+
+  configure(consumer: MiddlewareConsumer) {
+    const config: IConfAgent | undefined =
+      this.configService.get<IConfAgent>("agent");
+
+    if (config?.agentIsSVDX) {
+      consumer
+        .apply(BasicAuthMiddleware)
+        .forRoutes({ path: "*messages", method: RequestMethod.ALL });
+    }
+  }
+}
diff --git a/libs/askar/src/askar-rest/auth/basic.guard.ts b/libs/askar/src/askar-rest/auth/basic.guard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..354ea9ed785a36ed534e5536493034a23a7099f0
--- /dev/null
+++ b/libs/askar/src/askar-rest/auth/basic.guard.ts
@@ -0,0 +1,9 @@
+import { Injectable } from "@nestjs/common";
+import { AuthGuard } from "@nestjs/passport";
+
+/**
+ * Basic guard is NOT currently used, it is left for the  time when we implement jwt auth for the rest of the routes
+ */
+
+@Injectable()
+export class BasicGuard extends AuthGuard("basic") {}
diff --git a/libs/askar/src/askar-rest/auth/basic.middleware.ts b/libs/askar/src/askar-rest/auth/basic.middleware.ts
new file mode 100644
index 0000000000000000000000000000000000000000..25099e3a334f4c8448379ac88ed7673d3a1cb158
--- /dev/null
+++ b/libs/askar/src/askar-rest/auth/basic.middleware.ts
@@ -0,0 +1,48 @@
+import {
+  Injectable,
+  Logger,
+  NestMiddleware,
+  UnauthorizedException,
+} from "@nestjs/common";
+import { Request, Response, NextFunction } from "express";
+import { ConfigService } from "@nestjs/config";
+import { IConfAgent } from "@ocm-engine/config";
+
+@Injectable()
+export class BasicAuthMiddleware implements NestMiddleware {
+  private readonly logger: Logger = new Logger(BasicAuthMiddleware.name);
+
+  constructor(private readonly configService: ConfigService) {}
+
+  use(req: Request, res: Response, next: NextFunction) {
+    const config: IConfAgent | undefined =
+      this.configService.get<IConfAgent>("agent");
+
+    if (!config?.agentIsSVDX) {
+      this.logger.log("Agent is REST only turning of basic auth");
+
+      return next();
+    }
+
+    this.logger.log("Agent is SVDX turning basic auth middleware on");
+
+    const authHeader = req.headers["authorization"];
+
+    if (!authHeader) {
+      return next(new UnauthorizedException());
+    }
+
+    const [username, password] = Buffer.from(authHeader.split(" ")[1], "base64")
+      .toString()
+      .split(":");
+
+    if (
+      username === config.agentSVDXBasicUser &&
+      password === config.agentSVDXBasicPass
+    ) {
+      return next();
+    }
+
+    return next(new UnauthorizedException());
+  }
+}
diff --git a/libs/askar/src/askar-rest/auth/basic.strategy.ts b/libs/askar/src/askar-rest/auth/basic.strategy.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f454f0af8b0af6da4e6f71d3b7cb3319b22e4b1b
--- /dev/null
+++ b/libs/askar/src/askar-rest/auth/basic.strategy.ts
@@ -0,0 +1,30 @@
+import { ConfigService } from "@nestjs/config";
+import { IConfAgent } from "@ocm-engine/config";
+import { BasicStrategy as Strategy } from "passport-http";
+import { PassportStrategy } from "@nestjs/passport";
+import { Injectable, UnauthorizedException } from "@nestjs/common";
+
+/**
+ * Basic strategy is NOT currently used, it is left for the  time when we implement jwt auth for the rest of the routes
+ */
+@Injectable()
+export class BasicStrategy extends PassportStrategy(Strategy, "basic") {
+  constructor(private readonly configService: ConfigService) {
+    super();
+  }
+
+  async validate(username: string, password: string): Promise<boolean> {
+    console.log(username, password);
+    const config: IConfAgent | undefined =
+      this.configService.get<IConfAgent>("agent");
+
+    if (
+      config?.agentSVDXBasicUser === username &&
+      config?.agentSVDXBasicPass === password
+    ) {
+      return true;
+    }
+
+    throw new UnauthorizedException();
+  }
+}
diff --git a/libs/askar/src/askar-rest/rest.controller.ts b/libs/askar/src/askar-rest/rest.controller.ts
index 023783a692ca2f12a7c6fdf2c84257c4a6a2e0e5..8227d7dd6ab466a4ce94aa370eb68f31f7c8a1b5 100644
--- a/libs/askar/src/askar-rest/rest.controller.ts
+++ b/libs/askar/src/askar-rest/rest.controller.ts
@@ -1,4 +1,5 @@
 import { Body, Controller, Get, Param, Post, UseFilters } from "@nestjs/common";
+
 import { AgentService } from "../askar/agent.service";
 import {
   CreateCredentialDefinitionRequsetDto,
@@ -83,9 +84,9 @@ export class RestController {
     return this.agentService.getProofById(data.proofRecordId);
   }
 
-  @Post(`/credential/proof/:proof_record_id/accept`)
-  acceptProof(@Param("proof_record_id") proofRecordId: string) {
-    return this.agentService.acceptProof(proofRecordId);
+  @Post(`/credential/proof/accept`)
+  acceptProof(@Body() acceptProofRequestDto: AcceptProofRequestDto) {
+    return this.agentService.acceptProof(acceptProofRequestDto);
   }
 
   @Post(`/credential/proof/:proof_record_id/decline`)
diff --git a/libs/askar/src/askar/agent.event.listener.servce.ts b/libs/askar/src/askar/agent-event-listener.service.ts
similarity index 61%
rename from libs/askar/src/askar/agent.event.listener.servce.ts
rename to libs/askar/src/askar/agent-event-listener.service.ts
index 03eaf71d0507327cd89e83b680ae4cdfbcf21cf5..9cb3722871aefcae414e07427051dfe572d6fc69 100644
--- a/libs/askar/src/askar/agent.event.listener.servce.ts
+++ b/libs/askar/src/askar/agent-event-listener.service.ts
@@ -5,6 +5,10 @@ import {
   BasicMessageEventTypes,
   BasicMessageRole,
   BasicMessageStateChangedEvent,
+  ConnectionEventTypes,
+  ConnectionStateChangedEvent,
+  ProofEventTypes,
+  ProofStateChangedEvent,
 } from "@aries-framework/core";
 import {
   MakeBasicMessageResponseDto,
@@ -13,11 +17,15 @@ import {
 } from "@ocm-engine/dtos";
 import { IConfAgent } from "@ocm-engine/config";
 import { ConfigService } from "@nestjs/config";
+import {
+  svdxConnectionStateChangeHandler,
+  svdxProofStateChangeHandler,
+} from "../agent.utils";
 
 @Injectable()
-export class AgentEventListenerServce implements OnModuleInit {
-  private agentConfig: IConfAgent;
-  private readonly logger: Logger = new Logger(AgentEventListenerServce.name);
+export class AgentEventListenerService implements OnModuleInit {
+  private agentConfig: IConfAgent | undefined;
+  private readonly logger: Logger = new Logger(AgentEventListenerService.name);
 
   constructor(
     private readonly gatewayClient: GatewayClient,
@@ -27,8 +35,36 @@ export class AgentEventListenerServce implements OnModuleInit {
 
   onModuleInit(): void {
     this.logger.debug("Agent is listening for AFJ events");
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    this.agentConfig = this.configService.get<IConfAgent>("agent")!;
+    this.agentConfig = this.configService.get<IConfAgent>("agent");
+
+    if (this.agentConfig?.agentIsSVDX && this.agentConfig?.agentIsRest) {
+      this.askar.agent.events.on(
+        ConnectionEventTypes.ConnectionStateChanged,
+        async (ev: ConnectionStateChangedEvent) => {
+          this.logger.log("connection state event received");
+          this.logger.debug(JSON.stringify(ev, null, 2));
+          return svdxConnectionStateChangeHandler(
+            ev,
+            this.askar.agent,
+            this.agentConfig,
+          );
+        },
+      );
+
+      this.askar.agent.events.on(
+        ProofEventTypes.ProofStateChanged,
+        async (ev: ProofStateChangedEvent) => {
+          this.logger.log("proof state event received");
+          this.logger.debug(JSON.stringify(ev, null, 2));
+
+          return svdxProofStateChangeHandler(
+            ev,
+            this.askar.agent,
+            this.agentConfig,
+          );
+        },
+      );
+    }
 
     this.askar.agent.events.on(
       BasicMessageEventTypes.BasicMessageStateChanged,
@@ -46,7 +82,7 @@ export class AgentEventListenerServce implements OnModuleInit {
           dto.connectionId = ev.payload.basicMessageRecord.connectionId;
           dto.from = connectionInfo?.theirLabel;
 
-          if (this.agentConfig.agentIsRest) {
+          if (this.agentConfig?.agentIsRest) {
             this.logger.debug(
               "agent is configured as rest, webhook still not implemented",
             );
diff --git a/libs/askar/src/askar/agent.service.ts b/libs/askar/src/askar/agent.service.ts
index 72359aa5e6bc227a159ca324d2b213215168f654..d03a7226af0f1782e8f513fccc6243526392b396 100644
--- a/libs/askar/src/askar/agent.service.ts
+++ b/libs/askar/src/askar/agent.service.ts
@@ -2,6 +2,7 @@ import { Injectable } from "@nestjs/common";
 import { AskarService } from "./askar.service";
 import {
   AcceptInvitationResponseDto,
+  AcceptProofRequestDto,
   ConnectionNotFoundError,
   CreateCredentialDefinitionRequsetDto,
   CreateCredentialDefinitionResponseDto,
@@ -18,13 +19,19 @@ import {
   MakeBasicMessageResponseDto,
   SchemaNotCreatedError,
   DeclineProofResponseDto,
+  ListSingleConnectionResponseDto,
+  SchemaNotFoundError,
+  ListSingleSchemaResponseDto,
 } from "@ocm-engine/dtos";
 import {
+  AutoAcceptProof,
   CredentialState,
-  ProofExchangeRecord,
+  JsonEncoder,
   ProofState,
 } from "@aries-framework/core";
 import { AnonCredsRequestedAttribute } from "@aries-framework/anoncreds";
+import { uuid } from "@aries-framework/core/build/utils/uuid";
+import { waitForProofExchangeRecordSubject } from "../agent.utils";
 
 @Injectable()
 export class AgentService {
@@ -60,20 +67,100 @@ export class AgentService {
     return r;
   };
 
-  fetchConnections() {
-    return this.askar.agent.connections.getAll();
+  fetchConnections = async () => {
+    let responseFromAgent = await this.askar.agent.connections.getAll();
+
+    if (!responseFromAgent) {
+      throw new ConnectionNotFoundError();
+    }
+
+    type ConnectionList = typeof responseFromAgent;
+    type ConnectionSingleItem = ConnectionList[0];
+
+    let listResponseAll = responseFromAgent.map((singleConnection: ConnectionSingleItem) => {
+      let listResponseSingle = new ListSingleConnectionResponseDto();
+      listResponseSingle.connectionId = singleConnection.id;
+      listResponseSingle.createdAt = singleConnection.createdAt;
+      listResponseSingle.state = singleConnection.state;
+      listResponseSingle.role = singleConnection.role;
+      listResponseSingle.autoAcceptConnection = singleConnection.autoAcceptConnection;
+      listResponseSingle.outOfBandId = singleConnection?.outOfBandId;
+      listResponseSingle.updatedAt = singleConnection.updatedAt;
+      listResponseSingle.did = singleConnection.did;
+      listResponseSingle.theirLabel = singleConnection.theirLabel;
+      listResponseSingle.theirDid = singleConnection.theirDid;
+
+      return listResponseSingle;
+    })
+
+    return listResponseAll;
   }
 
-  getConnectionById = (id: string) => {
-    return this.askar.agent.connections.findById(id);
+  getConnectionById = async (id: string) => {
+    let responseFromAgent = await this.askar.agent.connections.findById(id);
+
+    if (!responseFromAgent) {
+      throw new ConnectionNotFoundError();
+    }
+
+    let listResponseSingle = new ListSingleConnectionResponseDto();
+    listResponseSingle.connectionId = responseFromAgent.id;
+    listResponseSingle.createdAt = responseFromAgent.createdAt;
+    listResponseSingle.state = responseFromAgent.state;
+    listResponseSingle.role = responseFromAgent.role;
+    listResponseSingle.autoAcceptConnection = responseFromAgent.autoAcceptConnection;
+    listResponseSingle.outOfBandId = responseFromAgent?.outOfBandId;
+    listResponseSingle.updatedAt = responseFromAgent.updatedAt;
+    listResponseSingle.did = responseFromAgent.did;
+    listResponseSingle.theirLabel = responseFromAgent.theirLabel;
+    listResponseSingle.theirDid = responseFromAgent.theirDid;
+
+    return [listResponseSingle];
   };
 
-  fetchSchemas = () => {
-    return this.askar.agent.modules.anoncreds.getCreatedSchemas({});
+  fetchSchemas = async () => {
+    let responseFromAgent = await this.askar.agent.modules.anoncreds.getCreatedSchemas({});
+
+    if (!responseFromAgent) {
+      throw new SchemaNotFoundError();
+    }
+
+    type SchemaList = typeof responseFromAgent;
+    type SchemaSingleItem = SchemaList[0];
+
+    let listResponseAll = responseFromAgent.map((singleSchema: SchemaSingleItem) => {
+      let listResponseSingle = new ListSingleSchemaResponseDto();
+      listResponseSingle.schemaId = singleSchema.schemaId;
+      listResponseSingle.version = singleSchema.schema.version;
+      listResponseSingle.schemaName = singleSchema.schema.name;
+      listResponseSingle.updatedAt = singleSchema.updatedAt;
+      listResponseSingle.attrNames = singleSchema.schema.attrNames;
+      listResponseSingle.issuerId = singleSchema.schema.issuerId;
+      listResponseSingle.methodName = singleSchema.methodName;
+
+      return listResponseSingle;
+    })
+
+    return listResponseAll;
   };
 
-  getSchemaById = (schemaId: string) => {
-    return this.askar.agent.modules.anoncreds.getSchema(schemaId);
+  getSchemaById = async (schemaId: string) => {
+    let responseFromAgent = await this.askar.agent.modules.anoncreds.getSchema(schemaId);
+    
+    if (!responseFromAgent || !responseFromAgent.schema) {
+      throw new SchemaNotFoundError();
+    }
+
+    let listResponseSingle = new ListSingleSchemaResponseDto();
+    listResponseSingle.schemaId = responseFromAgent.schemaId;
+    listResponseSingle.version = responseFromAgent.schema.version;
+    listResponseSingle.schemaName = responseFromAgent.schema.name;
+    listResponseSingle.attrNames = responseFromAgent.schema.attrNames;
+    // listResponseSingle.updatedAt = responseFromAgent.schema.updatedAt;
+    listResponseSingle.issuerId = responseFromAgent.schema.issuerId;
+    // listResponseSingle.methodName = responseFromAgent.methodName;
+
+    return [listResponseSingle];
   };
 
   createSchema = async (schema: CreateSchemaRequestDto) => {
@@ -230,11 +317,11 @@ export class AgentService {
   };
 
   issueProof = async (issueProofDto: IssueProofRequestDto) => {
-    let exchangeRecord: ProofExchangeRecord;
+    console.log(JSON.stringify(issueProofDto, null, 2));
     const requestedAttributes: Record<string, AnonCredsRequestedAttribute> = {};
 
     for (const attr of issueProofDto.attributes) {
-      requestedAttributes[attr.attributeName] = {
+      requestedAttributes[uuid()] = {
         name: attr.attributeName,
         restrictions: [
           {
@@ -246,32 +333,45 @@ export class AgentService {
     }
 
     if (!issueProofDto.connectionId) {
-      const { proofRecord } = await this.askar.agent.proofs.createRequest({
-        protocolVersion: "v2",
-        proofFormats: {
-          anoncreds: {
-            name: "proof-request",
-            version: "1.0",
-            requested_attributes: requestedAttributes,
+      console.log("connection Id not detected, creating oob proof");
+      const { proofRecord, message } =
+        await this.askar.agent.proofs.createRequest({
+          protocolVersion: "v2",
+          proofFormats: {
+            anoncreds: {
+              name: "proof-request",
+              version: "1.0",
+              requested_attributes: requestedAttributes,
+            },
           },
-        },
-      });
+          autoAcceptProof: AutoAcceptProof.ContentApproved,
+        });
 
-      exchangeRecord = proofRecord;
-    } else {
-      exchangeRecord = await this.askar.agent.proofs.requestProof({
-        protocolVersion: "v2",
-        connectionId: issueProofDto.connectionId,
-        proofFormats: {
-          anoncreds: {
-            name: "proof-request",
-            version: "1.0",
-            requested_attributes: requestedAttributes,
-          },
-        },
-      });
+      console.log({ proofRecord });
+      const { invitationUrl } =
+        await this.askar.agent.oob.createLegacyConnectionlessInvitation({
+          recordId: proofRecord.id,
+          message,
+          domain: this.askar.agentConfig.agentPeerAddress,
+        });
+
+      return { proofUrl: invitationUrl };
     }
 
+    console.log(`${issueProofDto.connectionId} detected, issuing proof`);
+
+    const exchangeRecord = await this.askar.agent.proofs.requestProof({
+      protocolVersion: "v2",
+      connectionId: issueProofDto.connectionId,
+      proofFormats: {
+        anoncreds: {
+          name: "proof-request",
+          version: "1.0",
+          requested_attributes: requestedAttributes,
+        },
+      },
+    });
+
     const response = new IssueProofResponseDto();
     response.proofId = exchangeRecord.id;
     response.connectionId = exchangeRecord.connectionId;
@@ -304,9 +404,9 @@ export class AgentService {
 
   getProofById = async (proofRecordId: string) => {
     const proofRecord = await this.askar.agent.proofs.findById(proofRecordId);
-    
+
     if (!proofRecord) {
-      return proofRecord
+      return proofRecord;
     }
 
     const proofResponse = new GetProofByIdResponseDto();
@@ -316,38 +416,70 @@ export class AgentService {
     proofResponse.state = proofRecord.state;
     proofResponse.updatedAt = proofRecord.updatedAt;
     proofResponse.createdAt = proofRecord.createdAt;
-    
-    
-    return proofResponse
+
+    return proofResponse;
+  };
+
+  acceptProof = async (acceptProofDto: AcceptProofRequestDto) => {
+    if (acceptProofDto.proofUrl) {
+      return this.acceptOobProof(acceptProofDto.proofUrl);
+    }
+    return this.acceptConnectionProof(acceptProofDto.proofRecordId);
+    // TODO: map to internal dto
   };
 
-  acceptProof = async (proofRecordId: string) => {
+  acceptOobProof = async (url: string) => {
+    const param = url.split("d_m=")[1];
+
+    const t = JsonEncoder.fromBase64(param);
+
+    await this.askar.agent.receiveMessage(t);
+
+    const record = await waitForProofExchangeRecordSubject(this.askar.agentR, {
+      state: ProofState.RequestReceived,
+    });
+
+    const response = new IssueProofResponseDto();
+
+    response.proofId = record.id;
+    response.state = record.state;
+    response.updatedAt = record.updatedAt;
+    response.createdAt = record.createdAt;
+
+    return response;
+  };
+
+  acceptConnectionProof = async (proofRecordId: string) => {
+    console.log(`accepting proof request for ${proofRecordId}`);
     const requestedCredentials =
       await this.askar.agent.proofs.selectCredentialsForRequest({
         proofRecordId,
       });
 
+    console.log(JSON.stringify(requestedCredentials, null, 2));
+
     const proof = await this.askar.agent.proofs.acceptRequest({
       proofRecordId,
       proofFormats: requestedCredentials.proofFormats,
     });
 
-    const t = new IssueProofResponseDto();
-    t.proofId = proof.id;
-    t.connectionId = proof.connectionId;
-    t.state = proof.state;
-    t.updatedAt = proof.updatedAt;
-    t.createdAt = proof.createdAt;
+    console.log(JSON.stringify(proof, null, 2));
 
-    return t;
-  };
+    const response = new IssueProofResponseDto();
+    response.proofId = proof.id;
+    response.connectionId = proof.connectionId;
+    response.state = proof.state;
+    response.updatedAt = proof.updatedAt;
+    response.createdAt = proof.createdAt;
 
+    return response;
+  };
 
   declineProofRequest = async (proofRecordId: string) => {
     const resultFromDecline = await this.askar.agent.proofs.declineRequest({
       proofRecordId,
       // sendProblemReport: false, // REVIEW: do we have a use case for this key?
-    })
+    });
 
     const declineResponse = new DeclineProofResponseDto();
     declineResponse.proofId = resultFromDecline.id;
@@ -361,6 +493,7 @@ export class AgentService {
 
   resolve = async (did: string) => {
     return this.askar.agent.dids.resolve(did);
+    // TODO: map to internal dto
   };
 
   sendMessage = async (message: MakeBasicMessageRequestDto) => {
diff --git a/libs/askar/src/askar/askar.module.ts b/libs/askar/src/askar/askar.module.ts
index 05a8706a87d787f04c2509461d5db4e9463974e0..c2f542cef457dd735b3ff5514299703b737bf903 100644
--- a/libs/askar/src/askar/askar.module.ts
+++ b/libs/askar/src/askar/askar.module.ts
@@ -3,7 +3,7 @@ import { AskarService } from "./askar.service";
 import { AgentService } from "./agent.service";
 import { ConfigModule } from "@nestjs/config";
 import { LedgersModule } from "@ocm-engine/ledgers";
-import { AgentEventListenerServce } from "./agent.event.listener.servce";
+import { AgentEventListenerService } from "./agent-event-listener.service";
 import { GatewayClient } from "@ocm-engine/clients";
 
 @Global()
@@ -12,7 +12,7 @@ import { GatewayClient } from "@ocm-engine/clients";
   providers: [
     AgentService,
     AskarService,
-    AgentEventListenerServce,
+    AgentEventListenerService,
     GatewayClient,
   ],
   exports: [AgentService, AskarService],
diff --git a/libs/askar/src/askar/askar.service.ts b/libs/askar/src/askar/askar.service.ts
index e07eb52a9f77a1f1b57ff7e0df2acdeebf9ec5e8..27c5307f0866f3cd1b07980fcac62b63759a9c91 100644
--- a/libs/askar/src/askar/askar.service.ts
+++ b/libs/askar/src/askar/askar.service.ts
@@ -7,10 +7,12 @@ import {
 
 import {
   Agent,
+  BaseEvent,
   ConsoleLogger,
   HttpOutboundTransport,
   InitConfig,
   LogLevel,
+  ProofEventTypes,
   TypedArrayEncoder,
   WsOutboundTransport,
 } from "@aries-framework/core";
@@ -22,12 +24,16 @@ import {
   generateKey,
   getAskarAnonCredsIndyModules,
   importDidsToWallet,
+  setupEventReplaySubjects,
+  setupSubjectTransports,
 } from "../agent.utils";
 import { IConfAgent } from "@ocm-engine/config";
+import { ReplaySubject } from "rxjs";
 
 @Injectable()
 export class AskarService implements OnModuleInit, OnModuleDestroy {
   public agent: Agent<ReturnType<typeof getAskarAnonCredsIndyModules>>;
+  public agentR: ReplaySubject<BaseEvent>;
   public agentConfig: IConfAgent;
   private readonly logger: Logger = new Logger(AskarService.name);
 
@@ -73,6 +79,14 @@ export class AskarService implements OnModuleInit, OnModuleDestroy {
     this.agent.registerOutboundTransport(new WsOutboundTransport());
     this.agent.registerOutboundTransport(new HttpOutboundTransport());
 
+    setupSubjectTransports([this.agent]);
+
+    const [agentR] = setupEventReplaySubjects(
+      [this.agent],
+      [ProofEventTypes.ProofStateChanged],
+    );
+
+    this.agentR = agentR;
     this.logger.log("Agent setup completed");
   }
 
diff --git a/libs/askar/src/askar/transports/agent.subject.inbound.transport.ts b/libs/askar/src/askar/transports/agent.subject.inbound.transport.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1a78cda63b11033b8eb096daec3831d1fdfc264d
--- /dev/null
+++ b/libs/askar/src/askar/transports/agent.subject.inbound.transport.ts
@@ -0,0 +1,80 @@
+import {
+  Agent,
+  AgentContext,
+  EncryptedMessage,
+  InboundTransport,
+  MessageReceiver,
+  TransportService,
+  TransportSession,
+} from "@aries-framework/core";
+import { Subject, Subscription } from "rxjs";
+import { uuid } from "@aries-framework/core/build/utils/uuid";
+import { SubjectMessage } from "../../agent.utils";
+
+class SubjectTransportSession implements TransportSession {
+  public id: string;
+  public readonly type = "subject";
+  private replySubject: Subject<SubjectMessage>;
+
+  public constructor(id: string, replySubject: Subject<SubjectMessage>) {
+    this.id = id;
+    this.replySubject = replySubject;
+  }
+
+  public async send(
+    agentContext: AgentContext,
+    encryptedMessage: EncryptedMessage,
+  ): Promise<void> {
+    this.replySubject.next({ message: encryptedMessage });
+  }
+
+  public async close(): Promise<void> {
+    this.replySubject.complete();
+  }
+}
+
+export class SubjectInboundTransport implements InboundTransport {
+  public readonly ourSubject: Subject<SubjectMessage>;
+  private subscription?: Subscription;
+
+  public constructor(ourSubject = new Subject<SubjectMessage>()) {
+    this.ourSubject = ourSubject;
+  }
+
+  public async start(agent: Agent) {
+    this.subscribe(agent);
+  }
+
+  public async stop() {
+    this.subscription?.unsubscribe();
+  }
+
+  private subscribe(agent: Agent) {
+    const logger = agent.config.logger;
+    const transportService = agent.dependencyManager.resolve(TransportService);
+    const messageReceiver = agent.dependencyManager.resolve(MessageReceiver);
+
+    this.subscription = this.ourSubject.subscribe({
+      next: async ({ message, replySubject }: SubjectMessage) => {
+        logger.test("Received message");
+
+        let session: SubjectTransportSession | undefined;
+        if (replySubject) {
+          session = new SubjectTransportSession(
+            `subject-session-${uuid()}`,
+            replySubject,
+          );
+
+          // When the subject is completed (e.g. when the session is closed), we need to
+          // remove the session from the transport service so it won't be used for sending messages
+          // in the future.
+          replySubject.subscribe({
+            complete: () => session && transportService.removeSession(session),
+          });
+        }
+
+        await messageReceiver.receiveMessage(message, { session });
+      },
+    });
+  }
+}
diff --git a/libs/askar/src/askar/transports/agent.subject.outbound.transport.ts b/libs/askar/src/askar/transports/agent.subject.outbound.transport.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4c3d77c2471c4935018874a66e9c13df20329586
--- /dev/null
+++ b/libs/askar/src/askar/transports/agent.subject.outbound.transport.ts
@@ -0,0 +1,80 @@
+import {
+  Agent,
+  AriesFrameworkError,
+  InjectionSymbols,
+  MessageReceiver,
+  OutboundPackage,
+  OutboundTransport,
+} from "@aries-framework/core";
+import { Logger } from "@nestjs/common";
+import { Subject, take, takeUntil } from "rxjs";
+import { SubjectMessage } from "../../agent.utils";
+
+export class SubjectOutboundTransport implements OutboundTransport {
+  private logger!: Logger;
+  private subjectMap: { [key: string]: Subject<SubjectMessage> | undefined };
+  private agent!: Agent;
+  private stop$!: Subject<boolean>;
+
+  public supportedSchemes = ["rxjs", "wss"];
+
+  public constructor(subjectMap: {
+    [key: string]: Subject<SubjectMessage> | undefined;
+  }) {
+    this.subjectMap = subjectMap;
+  }
+
+  public async start(agent: Agent): Promise<void> {
+    this.agent = agent;
+
+    this.logger = agent.dependencyManager.resolve(InjectionSymbols.Logger);
+    this.stop$ = agent.dependencyManager.resolve(InjectionSymbols.Stop$);
+  }
+
+  public async stop(): Promise<void> {
+    // No logic needed
+  }
+
+  public async sendMessage(outboundPackage: OutboundPackage) {
+    const messageReceiver =
+      this.agent.dependencyManager.resolve(MessageReceiver);
+    this.logger.debug(
+      `Sending outbound message to endpoint ${outboundPackage.endpoint}`,
+      {
+        endpoint: outboundPackage.endpoint,
+      },
+    );
+    const { payload, endpoint } = outboundPackage;
+
+    if (!endpoint) {
+      throw new AriesFrameworkError(
+        "Cannot send message to subject without endpoint",
+      );
+    }
+
+    const subject = this.subjectMap[endpoint];
+
+    if (!subject) {
+      throw new AriesFrameworkError(
+        `No subject found for endpoint ${endpoint}`,
+      );
+    }
+
+    // Create a replySubject just for this session. Both ends will be able to close it,
+    // mimicking a transport like http or websocket. Close session automatically when agent stops
+    const replySubject = new Subject<SubjectMessage>();
+    this.stop$
+      .pipe(take(1))
+      .subscribe(() => !replySubject.closed && replySubject.complete());
+
+    replySubject.pipe(takeUntil(this.stop$)).subscribe({
+      next: async ({ message }: SubjectMessage) => {
+        this.logger.debug("Received message");
+
+        await messageReceiver.receiveMessage(message);
+      },
+    });
+
+    subject.next({ message: payload, replySubject });
+  }
+}
diff --git a/libs/config/src/config/agent.config.ts b/libs/config/src/config/agent.config.ts
index 98e02af930dcaa8bec69d5b7c4b2b14486ca9094..c7fced916bc3e844873b808c453f09678b64f5ef 100644
--- a/libs/config/src/config/agent.config.ts
+++ b/libs/config/src/config/agent.config.ts
@@ -18,5 +18,11 @@ export const agentConfig = registerAs(
     agentConsumerMaxMessagess: parseInt(process.env["AGENT_MAX_MESSAGES"]!),
     agentConsumerRateLimit: parseInt(process.env["AGENT_RETE_LIMIT"]!),
     agentPort: parseInt(process.env["AGENT_PORT"]!),
+    agentIsSVDX: process.env["AGENT_IS_SVDX"] === "true",
+    agentSVDXSchemaId: process.env["AGENT_SVDX_SCHEMA_ID"]!,
+    agentSVDXCredDefId: process.env["AGENT_SVDX_CRED_DEF_ID"]!,
+    agentSVDXWebHook: process.env["AGENT_SVDX_WEBHOOK_URL"]!,
+    agentSVDXBasicUser: process.env["AGENT_SVDX_BASIC_USER"]!,
+    agentSVDXBasicPass: process.env["AGENT_SVDX_BASIC_PASS"]!,
   }),
 );
diff --git a/libs/config/src/interfaces/agent.config.interface.ts b/libs/config/src/interfaces/agent.config.interface.ts
index 1f0e7a85caa94710dd23ede1d6ff0d5042870a86..317b645a88d15a6b1eac322618bb706fabc12565 100644
--- a/libs/config/src/interfaces/agent.config.interface.ts
+++ b/libs/config/src/interfaces/agent.config.interface.ts
@@ -12,4 +12,11 @@ export interface IConfAgent {
   agentConsumerMaxMessagess: number;
   agentConsumerRateLimit: number;
   agentPort: number;
+
+  agentIsSVDX: boolean;
+  agentSVDXSchemaId: string;
+  agentSVDXCredDefId: string;
+  agentSVDXWebHook: string;
+  agentSVDXBasicUser: string;
+  agentSVDXBasicPass: string;
 }
diff --git a/libs/config/src/schemas/agent.schema.ts b/libs/config/src/schemas/agent.schema.ts
index 9cf569159b843b261c55387a444a11a52c39d2e6..46b36990cd6060f206dfcba92df03df3b4e6c8df 100644
--- a/libs/config/src/schemas/agent.schema.ts
+++ b/libs/config/src/schemas/agent.schema.ts
@@ -9,8 +9,12 @@ export const agentSchema = Joi.object({
   AGENT_DB_USER: Joi.string().required(),
   AGENT_DB_PASS: Joi.string().required(),
   AGENT_CONSUMER_NAME: Joi.string(),
-  AGENT_IS_REST: Joi.string().required(),
+  AGENT_IS_REST: Joi.string().optional(),
   AGENT_MAX_MESSAGES: Joi.string().required(),
   AGENT_RETE_LIMIT: Joi.string().required(),
   AGENT_PORT: Joi.string().required(),
+  AGENT_IS_SVDX: Joi.string().optional(),
+  AGENT_SVDX_SCHEMA_ID: Joi.string().optional(),
+  AGENT_SVDX_CRED_DEF_ID: Joi.string().optional(),
+  AGENT_SVDX_WEBHOOK_URL: Joi.string().optional(),
 });
diff --git a/libs/dtos/src/dtos/requests/accept.proof.request.dto.ts b/libs/dtos/src/dtos/requests/accept.proof.request.dto.ts
index 848258238ee20537fbefc58b906bbcf2d7119cc8..6f77a9cb2ccfdb05a7e1f9e8b167fcc2a44c3b4c 100644
--- a/libs/dtos/src/dtos/requests/accept.proof.request.dto.ts
+++ b/libs/dtos/src/dtos/requests/accept.proof.request.dto.ts
@@ -1,7 +1,13 @@
-import { IsNotEmpty, IsString } from "class-validator";
+import { IsNotEmpty, IsString, ValidateIf } from "class-validator";
 
 export class AcceptProofRequestDto {
   @IsString()
   @IsNotEmpty()
+  @ValidateIf((o) => o.proofUrl === undefined)
   proofRecordId: string;
+
+  @IsString()
+  @IsNotEmpty()
+  @ValidateIf((o) => o.proofRecordId === undefined)
+  proofUrl: string;
 }
diff --git a/libs/dtos/src/dtos/responses/list.connections.response.dto.ts b/libs/dtos/src/dtos/responses/list.connections.response.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42302ddd228bc6baf4bcab658c74eff11cd6f082
--- /dev/null
+++ b/libs/dtos/src/dtos/responses/list.connections.response.dto.ts
@@ -0,0 +1,37 @@
+import { IsBoolean, IsDateString, IsNotEmpty, IsString } from "class-validator";
+
+export class ListSingleConnectionResponseDto {
+    @IsNotEmpty()
+    @IsString()
+    connectionId: string;
+
+    @IsNotEmpty()
+    @IsDateString()
+    createdAt: Date;
+
+    @IsNotEmpty()
+    @IsString()
+    state: string;
+
+    @IsNotEmpty()
+    @IsString()
+    role: string;
+
+    @IsBoolean()
+    autoAcceptConnection?: boolean;
+
+    @IsString()
+    outOfBandId?: string;
+
+    @IsDateString()
+    updatedAt?: Date;
+
+    @IsString()
+    did?: string;
+
+    @IsString()
+    theirLabel?: string;
+
+    @IsString()
+    theirDid?: string;
+}
\ No newline at end of file
diff --git a/libs/dtos/src/dtos/responses/list.schema.response.dto.ts b/libs/dtos/src/dtos/responses/list.schema.response.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..833ca1627b82dc3983b29d47690e3687ba82f08b
--- /dev/null
+++ b/libs/dtos/src/dtos/responses/list.schema.response.dto.ts
@@ -0,0 +1,26 @@
+import { IsDateString, IsNotEmpty, IsString } from "class-validator";
+
+export class ListSingleSchemaResponseDto {
+    @IsNotEmpty()
+    @IsString()
+    schemaId: string;
+
+    @IsNotEmpty()
+    @IsString()
+    version?: string;
+
+    @IsDateString()
+    updatedAt?: Date;
+
+    @IsString()
+    issuerId?: string;
+
+    @IsString()
+    methodName?: string;
+
+    @IsNotEmpty()
+    attrNames: string[];
+
+    @IsString()
+    schemaName?: string;
+}
diff --git a/libs/dtos/src/errors/schema.not.found.error.ts b/libs/dtos/src/errors/schema.not.found.error.ts
new file mode 100644
index 0000000000000000000000000000000000000000..68ba71472c68dcc63b398fa3e2f8bbb2f246d648
--- /dev/null
+++ b/libs/dtos/src/errors/schema.not.found.error.ts
@@ -0,0 +1,10 @@
+export class SchemaNotFoundError extends Error {
+  constructor(message = "Schema not found") {
+    super(message);
+    this.name = "SchemaNotFoundError";
+
+    if (Error.captureStackTrace) {
+      Error.captureStackTrace(this, SchemaNotFoundError);
+    }
+  }
+}
\ No newline at end of file
diff --git a/libs/dtos/src/events/dtoToEventTransformer.ts b/libs/dtos/src/events/dtoToEventTransformer.ts
index 8365ac1b1600e83f6c5fbea1cac3fa4f911295d2..a120dee89f47017180b2ffa1d8a3eeab2bf48fd9 100644
--- a/libs/dtos/src/events/dtoToEventTransformer.ts
+++ b/libs/dtos/src/events/dtoToEventTransformer.ts
@@ -17,6 +17,7 @@ import { IssueProofRequestDto } from "../dtos/requests/issue.proof.request.dto";
 import { AcceptCredentialOfferRequestDto } from "../dtos/requests/accept.credential.offer.request.dto";
 import { MakeBasicMessageResponseDto } from "../dtos/responses/make.basic.message.response.dto";
 import { MakeBasicMessageRequestDto } from "../dtos/requests/make.basic.message.request.dto";
+import { AcceptProofRequestDto } from "../dtos/requests/accept.proof.request.dto";
 import { GetProofByIdResponseDto } from "../dtos/responses/get.proof.response.dto";
 import { DeclineProofRequestDto } from '../dtos/requests/decline.proof.request.dto';
 import { DeclineProofResponseDto } from "../dtos/responses/decline.proof.response.dto";
@@ -28,6 +29,8 @@ export const makeEvent = (payload: {
     | AcceptCredentialOfferRequestDto
     | CreateInvitationResponseDto
     | GetConnectionRequestDto
+    | CreateSchemaRequestDto
+    | AcceptProofRequestDto
     | DeclineProofRequestDto
     | DeclineProofResponseDto
     | CreateSchemaRequestDto
diff --git a/libs/dtos/src/index.ts b/libs/dtos/src/index.ts
index ce0ac84aac42b0426913d8f6ed022b7e085fc050..4f3bed1be6ef7cff4a2ac3c50d272e18c4807e47 100644
--- a/libs/dtos/src/index.ts
+++ b/libs/dtos/src/index.ts
@@ -21,12 +21,15 @@ export * from "./dtos/responses/gateway.accepted.response.dto";
 export * from "./dtos/responses/make.basic.message.response.dto";
 export * from "./dtos/responses/get.proof.response.dto";
 export * from "./dtos/responses/decline.proof.response.dto";
+export * from "./dtos/responses/list.connections.response.dto";
+export * from "./dtos/responses/list.schema.response.dto";
 
 export * from "./errors/connection.not.found.error";
 export * from "./errors/schema.not.created.error";
 export * from "./errors/credential.not.created.error";
 export * from "./errors/ledger.provider.fail.registration.error";
 export * from "./errors/connection.unsupported.type.error";
+export * from "./errors/schema.not.found.error";
 
 export * from "./events/event";
 export * from "./events/types";
diff --git a/package.json b/package.json
index 4b178adf4a117e61fe82bbee9f0114b899f7593c..9979d29e05059f82ce25ba14d6862250ac668218 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
     "@nestjs/config": "^2.3.1",
     "@nestjs/core": "^9.0.0",
     "@nestjs/microservices": "^9.4.2",
+    "@nestjs/passport": "^10.0.1",
     "@nestjs/platform-express": "^9.0.0",
     "@nestjs/platform-ws": "^10.1.3",
     "@nestjs/websockets": "^9.4.2",
@@ -51,6 +52,9 @@
     "cloudevents": "^7.0.0",
     "joi": "^17.9.2",
     "nats": "^2.14.0",
+    "passport": "^0.6.0",
+    "passport-http": "^0.3.0",
+    "passport-local": "^1.0.0",
     "reflect-metadata": "^0.1.13",
     "rxjs": "^7.0.0",
     "tslib": "^2.3.0",
@@ -83,6 +87,8 @@
     "@types/async-retry": "^1.4.5",
     "@types/jest": "^29.4.0",
     "@types/node": "~18.7.1",
+    "@types/passport-http": "^0.3.9",
+    "@types/passport-local": "^1.0.35",
     "@typescript-eslint/eslint-plugin": "^5.58.0",
     "@typescript-eslint/parser": "^5.58.0",
     "concurrently": "^8.2.0",
diff --git a/yarn.lock b/yarn.lock
index 9b857ac58a18edcb876f55ba20d6a865edc57975..2766f1095dc46380e23bf57b0170333df647dd1f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1676,6 +1676,11 @@
     iterare "1.2.1"
     tslib "2.5.3"
 
+"@nestjs/passport@^10.0.1":
+  version "10.0.1"
+  resolved "https://registry.yarnpkg.com/@nestjs/passport/-/passport-10.0.1.tgz#4a745cb4acf01ef8fd56b9ec1349ac74165b098f"
+  integrity sha512-hS22LeNj0LByS9toBPkpKyZhyKAXoHACLS1EQrjbAJJEQjhocOskVGwcMwvMlz+ohN+VU804/nMF1Zlya4+TiQ==
+
 "@nestjs/platform-express@^9.0.0":
   version "9.4.3"
   resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-9.4.3.tgz#f61b75686bdfce566be3b54fa7bb20a4d87ed619"
@@ -2899,6 +2904,38 @@
   resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
   integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
 
+"@types/passport-http@^0.3.9":
+  version "0.3.9"
+  resolved "https://registry.yarnpkg.com/@types/passport-http/-/passport-http-0.3.9.tgz#268e483ade820d4f0edb3d35cec090d1990cc081"
+  integrity sha512-uQ4vyRdvM0jdWuKpLmi6Q6ri9Nwt8YnHmF7kE6snbthxPrsMWcjRCVc5WcPaQ356ODSZTDgiRYURMPIspCkn3Q==
+  dependencies:
+    "@types/express" "*"
+    "@types/passport" "*"
+
+"@types/passport-local@^1.0.35":
+  version "1.0.35"
+  resolved "https://registry.yarnpkg.com/@types/passport-local/-/passport-local-1.0.35.tgz#233d370431b3f93bb43cf59154fb7519314156d9"
+  integrity sha512-K4eLTJ8R0yYW8TvCqkjB0pTKoqfUSdl5PfZdidTjV2ETV3604fQxtY6BHKjQWAx50WUS0lqzBvKv3LoI1ZBPeA==
+  dependencies:
+    "@types/express" "*"
+    "@types/passport" "*"
+    "@types/passport-strategy" "*"
+
+"@types/passport-strategy@*":
+  version "0.2.35"
+  resolved "https://registry.yarnpkg.com/@types/passport-strategy/-/passport-strategy-0.2.35.tgz#e52f5212279ea73f02d9b06af67efe9cefce2d0c"
+  integrity sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==
+  dependencies:
+    "@types/express" "*"
+    "@types/passport" "*"
+
+"@types/passport@*":
+  version "1.0.12"
+  resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.12.tgz#7dc8ab96a5e895ec13688d9e3a96920a7f42e73e"
+  integrity sha512-QFdJ2TiAEoXfEQSNDISJR1Tm51I78CymqcBa8imbjo6dNNu+l2huDxxbDEIoFIwOSKMkOfHEikyDuZ38WwWsmw==
+  dependencies:
+    "@types/express" "*"
+
 "@types/qs@*":
   version "6.9.7"
   resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
@@ -8901,6 +8938,34 @@ parseurl@~1.3.2, parseurl@~1.3.3:
   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
   integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
 
+passport-http@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/passport-http/-/passport-http-0.3.0.tgz#8ee53d4380be9c60df2151925029826f77115603"
+  integrity sha512-OwK9DkqGVlJfO8oD0Bz1VDIo+ijD3c1ZbGGozIZw+joIP0U60pXY7goB+8wiDWtNqHpkTaQiJ9Ux1jE3Ykmpuw==
+  dependencies:
+    passport-strategy "1.x.x"
+
+passport-local@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee"
+  integrity sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==
+  dependencies:
+    passport-strategy "1.x.x"
+
+passport-strategy@1.x.x:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"
+  integrity sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==
+
+passport@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/passport/-/passport-0.6.0.tgz#e869579fab465b5c0b291e841e6cc95c005fac9d"
+  integrity sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==
+  dependencies:
+    passport-strategy "1.x.x"
+    pause "0.0.1"
+    utils-merge "^1.0.1"
+
 path-exists@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@@ -8966,6 +9031,11 @@ path-type@^4.0.0:
   resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
   integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
 
+pause@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d"
+  integrity sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==
+
 picocolors@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
@@ -11063,7 +11133,7 @@ util@^0.12.4:
     is-typed-array "^1.1.3"
     which-typed-array "^1.1.2"
 
-utils-merge@1.0.1:
+utils-merge@1.0.1, utils-merge@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
   integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==