diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..9b51b9d538ebbea0432eaf782494bdda9444517e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +tmp +tools +compose +.* +dist diff --git a/.env.example b/.env.example index e66463c709c7879153166b641d2f3b764b076bc2..0df2d409e8093640770ca7ef8b7f2f4c22d52b4b 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ LEDGERS="BCOVRIN_TEST" IDUNION_KEY=#add if you are using IDUNION as a ledger -AGENT_PEER_URL="http://localhost:4000" +AGENT_PEER_URL="http://localhost:8001" AGENT_NAME=EXAMPLE_AGENT_45 AGENT_KEY=EXAMPLE_AGENT_45_KEY AGENT_DID_SEED=200000000000000000000000ExampleT21 #random string min 32 chars diff --git a/OCM Gateway.postman_collection.json b/OCM Gateway.postman_collection.json new file mode 100644 index 0000000000000000000000000000000000000000..be7c2032aba75585506237f810b9845eb562e2bf --- /dev/null +++ b/OCM Gateway.postman_collection.json @@ -0,0 +1,2413 @@ +{ + "info": { + "_postman_id": "db24c889-0f25-4851-b3a6-c8f036119252", + "name": "OCM Gateway", + "description": "OCM ENGINE GATEWAY API", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "1453906", + "_collection_link": "https://interstellar-resonance-579562.postman.co/workspace/My-Workspace~0fb5d194-7df6-48c6-8d80-b735c624826a/collection/1453906-db24c889-0f25-4851-b3a6-c8f036119252?action=share&creator=1453906&source=collection_link" + }, + "item": [ + { + "name": "api", + "item": [ + { + "name": "v1", + "item": [ + { + "name": "schemas-by-id", + "item": [ + { + "name": "Get schema by id", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"did:indy:LEDNGER:SXM76gQwRnjkgoz2oBnGjd/anoncreds/v0/SCHEMA/test schema/1.0.2\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas-by-id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas-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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"did:indy:LEDNGER:SXM76gQwRnjkgoz2oBnGjd/anoncreds/v0/SCHEMA/test schema/1.0.2\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas-by-id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas-by-id" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"did:indy:LEDNGER:SXM76gQwRnjkgoz2oBnGjd/anoncreds/v0/SCHEMA/test schema/1.0.2\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas-by-id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas-by-id" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"schemaId must be a string\",\n \"schemaId should not be empty\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"did:indy:LEDNGER:SXM76gQwRnjkgoz2oBnGjd/anoncreds/v0/SCHEMA/test schema/1.0.2\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas-by-id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas-by-id" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "schemas", + "item": [ + { + "name": "Create schema", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"my test schema\",\n \"attributes\": [\n \"first_name, last_name\"\n ],\n \"version\": \"/1015535231.*/\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + }, + "description": "Method will create schema. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"my test schema\",\n \"attributes\": [\n \"first_name, last_name\"\n ],\n \"version\": \"/1015535231.*/\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"my test schema\",\n \"attributes\": [\n \"first_name, last_name\"\n ],\n \"version\": \"/1015535231.*/\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"name must be a string\",\n \"name should not be empty\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"my test schema\",\n \"attributes\": [\n \"first_name, last_name\"\n ],\n \"version\": \"/1015535231.*/\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + }, + { + "name": "List all schemas", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + }, + "description": "Method will fetch all schemas. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/schemas", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "schemas" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "messages", + "item": [ + { + "name": "Send basic message", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"message\": \"hello world\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/messages", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "messages" + ] + }, + "description": "Method will send basic message to a connection. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"message\": \"hello world\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/messages", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "messages" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Untitled Response", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"message\": \"hello world\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/messages", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "messages" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"message\": \"hello world\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/messages", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "messages" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"connectionId must be a string\",\n \"connectionId should not be empty\",\n \"message must be a string\",\n \"message should not be empty\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"message\": \"hello world\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/messages", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "messages" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "invitations", + "item": [ + { + "name": "accept", + "item": [ + { + "name": "Accept invitation for connection", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"invitationUrl\": \"http://0.0.0.0:8001?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIzYWExNGIzNC04YTk5LTQxY2UtYTY3NC1jODUxYmVhMTIxMWEiLCJsYWJlbCI6IkRFeGNWYXNkX0FHRU5UXzQ1IiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly8wLjAuMC4wOjgwMDEiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa3VFcHllc1pNa3k0a1BpQzhEOEplZERlcm55YTFuaTREMUF3ZmdnWWt6YmR4Il0sInJvdXRpbmdLZXlzIjpbXX1dfQ\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/invitations/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations", + "accept" + ] + }, + "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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"invitationUrl\": \"http://0.0.0.0:8001?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIzYWExNGIzNC04YTk5LTQxY2UtYTY3NC1jODUxYmVhMTIxMWEiLCJsYWJlbCI6IkRFeGNWYXNkX0FHRU5UXzQ1IiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly8wLjAuMC4wOjgwMDEiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa3VFcHllc1pNa3k0a1BpQzhEOEplZERlcm55YTFuaTREMUF3ZmdnWWt6YmR4Il0sInJvdXRpbmdLZXlzIjpbXX1dfQ\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/invitations/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations", + "accept" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"invitationUrl\": \"http://0.0.0.0:8001?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIzYWExNGIzNC04YTk5LTQxY2UtYTY3NC1jODUxYmVhMTIxMWEiLCJsYWJlbCI6IkRFeGNWYXNkX0FHRU5UXzQ1IiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly8wLjAuMC4wOjgwMDEiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa3VFcHllc1pNa3k0a1BpQzhEOEplZERlcm55YTFuaTREMUF3ZmdnWWt6YmR4Il0sInJvdXRpbmdLZXlzIjpbXX1dfQ\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/invitations/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations", + "accept" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"invitationUrl must be a string\",\n \"invitationUrl should not be empty\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"invitationUrl\": \"http://0.0.0.0:8001?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4xL2ludml0YXRpb24iLCJAaWQiOiIzYWExNGIzNC04YTk5LTQxY2UtYTY3NC1jODUxYmVhMTIxMWEiLCJsYWJlbCI6IkRFeGNWYXNkX0FHRU5UXzQ1IiwiYWNjZXB0IjpbImRpZGNvbW0vYWlwMSIsImRpZGNvbW0vYWlwMjtlbnY9cmZjMTkiXSwiaGFuZHNoYWtlX3Byb3RvY29scyI6WyJodHRwczovL2RpZGNvbW0ub3JnL2RpZGV4Y2hhbmdlLzEuMCIsImh0dHBzOi8vZGlkY29tbS5vcmcvY29ubmVjdGlvbnMvMS4wIl0sInNlcnZpY2VzIjpbeyJpZCI6IiNpbmxpbmUtMCIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHA6Ly8wLjAuMC4wOjgwMDEiLCJ0eXBlIjoiZGlkLWNvbW11bmljYXRpb24iLCJyZWNpcGllbnRLZXlzIjpbImRpZDprZXk6ejZNa3VFcHllc1pNa3k0a1BpQzhEOEplZERlcm55YTFuaTREMUF3ZmdnWWt6YmR4Il0sInJvdXRpbmdLZXlzIjpbXX1dfQ\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/invitations/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations", + "accept" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:4312\"\n}" + } + ] + } + ] + }, + { + "name": "Create invitation for connection", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/invitations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations" + ] + }, + "description": "Method will create invitation url. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/invitations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/invitations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "invitations" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:4312\"\n}" + } + ] + } + ] + }, + { + "name": "credentials", + "item": [ + { + "name": "proof", + "item": [ + { + "name": "{proof_record_id}", + "item": [ + { + "name": "accept", + "item": [ + { + "name": "Accept credential proof", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/:proof_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + ":proof_record_id", + "accept" + ], + "variable": [ + { + "key": "proof_record_id", + "value": "est ullamco in" + } + ] + }, + "description": "Method accept credential proof. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/:proof_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + ":proof_record_id", + "accept" + ], + "variable": [ + { + "key": "proof_record_id" + } + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/:proof_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + ":proof_record_id", + "accept" + ], + "variable": [ + { + "key": "proof_record_id" + } + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1919\"\n}" + } + ] + } + ] + } + ] + }, + { + "name": "issue", + "item": [ + { + "name": "Issue proof for credential", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"attributes\": [\n {\n \"attributeName\": \"proident eu ea dolore\",\n \"credentialDefinitionId\": \"dolore Ut sit\",\n \"schemaId\": \"enim in proident dolore\"\n },\n {\n \"attributeName\": \"nisi\",\n \"credentialDefinitionId\": \"minim commodo non\",\n \"schemaId\": \"anim cupidatat ad Duis eiusmod\"\n }\n ],\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + "issue" + ] + }, + "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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"attributes\": [\n {\n \"attributeName\": \"proident eu ea dolore\",\n \"credentialDefinitionId\": \"dolore Ut sit\",\n \"schemaId\": \"enim in proident dolore\"\n },\n {\n \"attributeName\": \"nisi\",\n \"credentialDefinitionId\": \"minim commodo non\",\n \"schemaId\": \"anim cupidatat ad Duis eiusmod\"\n }\n ],\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + "issue" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"attributes\": [\n {\n \"attributeName\": \"proident eu ea dolore\",\n \"credentialDefinitionId\": \"dolore Ut sit\",\n \"schemaId\": \"enim in proident dolore\"\n },\n {\n \"attributeName\": \"nisi\",\n \"credentialDefinitionId\": \"minim commodo non\",\n \"schemaId\": \"anim cupidatat ad Duis eiusmod\"\n }\n ],\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + "issue" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"attributes must contain at least 1 elements\",\n \"attributes must be an array\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"attributes\": [\n {\n \"attributeName\": \"proident eu ea dolore\",\n \"credentialDefinitionId\": \"dolore Ut sit\",\n \"schemaId\": \"enim in proident dolore\"\n },\n {\n \"attributeName\": \"nisi\",\n \"credentialDefinitionId\": \"minim commodo non\",\n \"schemaId\": \"anim cupidatat ad Duis eiusmod\"\n }\n ],\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof", + "issue" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1919\"\n}" + } + ] + } + ] + }, + { + "name": "List received unaccepted proofs", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof" + ] + }, + "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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/proof", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "proof" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1919\"\n}" + } + ] + } + ] + }, + { + "name": "offers", + "item": [ + { + "name": "{credential_record_id}", + "item": [ + { + "name": "accept", + "item": [ + { + "name": "Accept credential offers", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers/:credential_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "offers", + ":credential_record_id", + "accept" + ], + "variable": [ + { + "key": "credential_record_id", + "value": "est ullamco in" + } + ] + }, + "description": "Method list accept credential offer. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers/:credential_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "offers", + ":credential_record_id", + "accept" + ], + "variable": [ + { + "key": "credential_record_id" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Untitled Response", + "originalRequest": { + "method": "POST", + "header": [], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers/:credential_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "offers", + ":credential_record_id", + "accept" + ], + "variable": [ + { + "key": "credential_record_id" + } + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers/:credential_record_id/accept", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "offers", + ":credential_record_id", + "accept" + ], + "variable": [ + { + "key": "credential_record_id" + } + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + } + ] + }, + { + "name": "List unaccepted credential offers", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "offers" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/offers", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "offers" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "issue", + "item": [ + { + "name": "Issue credential", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"credentialDefinitionId\": \"eiusmod\",\n \"attributes\": [\n {\n \"name\": \"veniam sunt in et\",\n \"value\": \"aliquip sed cillum ut\"\n },\n {\n \"name\": \"ut fugiat aute sed\",\n \"value\": \"ea\"\n }\n ]\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "issue" + ] + }, + "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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"credentialDefinitionId\": \"eiusmod\",\n \"attributes\": [\n {\n \"name\": \"veniam sunt in et\",\n \"value\": \"aliquip sed cillum ut\"\n },\n {\n \"name\": \"ut fugiat aute sed\",\n \"value\": \"ea\"\n }\n ]\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "issue" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"credentialDefinitionId\": \"eiusmod\",\n \"attributes\": [\n {\n \"name\": \"veniam sunt in et\",\n \"value\": \"aliquip sed cillum ut\"\n },\n {\n \"name\": \"ut fugiat aute sed\",\n \"value\": \"ea\"\n }\n ]\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "issue" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"connectionId must be a string\",\n \"connectionId should not be empty\",\n \"credentialDefinitionId must be a string\",\n \"credentialDefinitionId should not be empty\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"connectionId\": \"6464b521-005a-4379-91e0-a3692b31cafd\",\n \"credentialDefinitionId\": \"eiusmod\",\n \"attributes\": [\n {\n \"name\": \"veniam sunt in et\",\n \"value\": \"aliquip sed cillum ut\"\n },\n {\n \"name\": \"ut fugiat aute sed\",\n \"value\": \"ea\"\n }\n ]\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/issue", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "issue" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "definition", + "item": [ + { + "name": "Create credential definition", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"exercitation minim pariatur\",\n \"tag\": \"voluptate eiusmod\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/definition", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "definition" + ] + }, + "description": "Method create credential definition. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"exercitation minim pariatur\",\n \"tag\": \"voluptate eiusmod\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/definition", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "definition" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "Validation error", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"exercitation minim pariatur\",\n \"tag\": \"voluptate eiusmod\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/definition", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "definition" + ] + } + }, + "status": "Bad Request", + "code": 400, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 400,\n \"message\": [\n \"schemaId must be a string\",\n \"schemaId should not be empty\",\n \"tag must be a string\",\n \"tag should not be empty\"\n ],\n \"error\": \"Bad Request\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"schemaId\": \"exercitation minim pariatur\",\n \"tag\": \"voluptate eiusmod\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/v1/credentials/definition", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials", + "definition" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "List all credential", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials" + ] + }, + "description": "Method list credential definition no filters applied. The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/credentials", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "credentials" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:1234\"\n}" + } + ] + } + ] + }, + { + "name": "connections", + "item": [ + { + "name": "{id}", + "item": [ + { + "name": "Get connection by id", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/connections/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "connections", + ":id" + ], + "variable": [ + { + "key": "id", + "value": "est ullamco in" + } + ] + }, + "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" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/connections/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "connections", + ":id" + ], + "variable": [ + { + "key": "id" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/connections/:id", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "connections", + ":id" + ], + "variable": [ + { + "key": "id" + } + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:4312\"\n}" + } + ] + } + ] + }, + { + "name": "List all connections", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/connections", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "connections" + ] + }, + "description": "The id of the response will be matched when you receive event from the websocket" + }, + "response": [ + { + "name": "Request is accepted for execution, the response id will match the event id received from the web socket", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/connections", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "connections" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"80633e6d-c606-4539-a3df-287fedd09253\"\n}" + }, + { + "name": "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.", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/connections", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "connections" + ] + } + }, + "status": "Internal Server Error", + "code": 500, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"statusCode\": 500,\n \"message\": \"connect ECONNREFUSED 0.0.0.0.0:4312\"\n}" + } + ] + } + ] + } + ] + } + ] + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "http://0.0.0.0:8081" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 16287d32eb8061a5a8ace8e78a945bec88274128..d186f2c2ba314a8d1a7d7f21e4f82f3bcd497959 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,158 @@ -# Ocm Engine +# OCM Engine -<a alt="Nx logo" href="https://nx.dev" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="45"></a> +- [Introduction](#introduction) +- [Requirements](#requirements) +- [Architecture](#architecture) +- [Setup](#setup) +- [Local env](#local) +- [Docker env](#docker) +- [Usage](#usage-via-postman) +- [Example](#send-didcomm-messages-between-two-ocms) -✨ **This workspace has been generated by [Nx, a Smart, fast and extensible build system.](https://nx.dev)** ✨ +## Introduction -## Further help +OCM Engine is a monorepo based on [NestJS](http://nestjs.com) and [Nx](https://nx.dev), holding applications in `apps` directory and `libraries` in `libs`, which were used to create the applications and can be used for developing additional applications in `OCM` project. + +### Apps list: + - Agent + - Attestation Manager + - Connection Manager + - Proof Manager + - Gateway + +### Library list: + - Askar + - Clients + - Config + - Dtos + - Ledgers + - Nats + +## Requirements + +- Git +- NodeJS >= v18.16.0 +- PostgresDB +- Nats + +## Architecture + +```mermaid +flowchart TD + Postman --http--> Gateway + Gateway --ws--> Postman + Gateway --tcp--> cm[Connection Manager] & am[Attestation Manager] & pm[Proof Manager] --event--> nats[NATS] + nats --event--> Agent + Agent --tcp--> Gateway + Agent <--> db[(PostgresDB)] + Agent <--> Ledger[(Ledger)] +``` + +## Setup + +- ##### Install Git + + How to install [Git](https://www.atlassian.com/git/tutorials/install-git) on my system. + +- ##### Install NodeJS >= v18.16.0 version + + How to install [NodeJS](https://nodejs.org/en/download/package-manager) on my system. + Second option is to use version manager like [nvm](https://github.com/nvm-sh/nvm) which will allow you to switch between different NodeJS versions. + +- ##### Clone the repo + + Once you have installed all Git, Node, Yarn you can clone the project with: + + ``` + git clone git@code.vereign.com:gaiax/ocm/ocm-engine.git + ``` + or + + ``` + git clone https://code.vereign.com/gaiax/ocm/ocm-engine.git + ``` + + +- ##### Install Dependencies + + Go inside your cloned repo and install all dependencies with: + ``` + yarn install + ``` + +## Local + You can run the entire stack or specific application locally. + + Example for entire stack: + + 1. copy .env.example to .env + 2. edit .env to your liking + 3. yarn install + 4. yarn infra:local or install PostgresDB and Nats broker locally and add them to .env + 5. yarn serve:all + + Example of running only the agent service as a rest service. + + 1. copy .env.example to .env + 2. edit .env to your liking and change AGENT_IS_REST to true + 3. yarn install + 4. yarn infra:local or isntall PostgresDB and Nats broker locally and add them to .env + 5. yarn serve:agent + +## Docker + +Example: + + You can `issuer` OCM stack with: + + 1. edit issuer.env in compose directory + 2. yarn infra:issuer + + Then the gateway will be at http://localhost:8081 url + + `Holder` OCM stack can be started with: + + 1. edit holder.env in compose directory + 2. yarn infra:holder + + Then the gateway will be at http://localhost:8082 url + + You can run the entire stack - `issuer` and `holder` with: + + 1. edit issuer.env and holder.env in compose directory + 2. yarn infra + + Yarn commands are wrapper around docker-compose for easier use. You can still use docker-compose from compose dir. + +## Usage via Postman + 1. Import postman collection from the repo + 2. Connect to Socket.io on the gateway address, to listen for responses with [postman](https://learning.postman.com/docs/sending-requests/websocket/websocket) event is "message" + 3. Make a request + 4. Response will be sent to the Socket.io + +## Send Didcomm messages between two OCMs + +1. Setup [Postman](#usage-via-postman) as the previous step +2. Check your local ip - on linux and macos - ifconfig, windows - ipconfig +3. Edit [issuer.env](compose/env/issuer.env) + - Change `AGENT_PEER_URL` to use your local ip - `http://your-local-ip:8001` - EXAMPLE `http://192.168.111.53:8001` + - Change `AGENT_NAME` and `AGENT_KEY` - those are the name and the key of the wallet + - Change `AGENT_DID_SEED` - this is a seed for private key from which the DID will be created. +4. Start the issuer with `yarn run infra:issuer` or `npm run infra:issuer` +5. Connect to the socket via postman. `ws://localhost:8081` +6. `Create new invitation` via postman request, on the socket listener you will receive invitation url response +7. Copy and paste this url in the chat + + +8. Another OCM (which performed the same setup steps, but with different values) should get this invitation url +8. Call `accept invitation` via postman with this invitation url as a body payload +9. Response will be returned on the socket, that a connection is made. +10. Get the connectionId from this response +11. Send basic message with connectionId and a string message + + +12. On the socket of issuer a event will be received with the message and connection id. + +## License +This project is licensed under the AGPL License - see the [LICENSE](LICENSE) file for details. -Visit the [Nx Documentation](https://nx.dev) to learn more. diff --git a/apps/agent/README.md b/apps/agent/README.md new file mode 100644 index 0000000000000000000000000000000000000000..865d2b07fb534644b1ac3b5601ebc0a484f2a3df --- /dev/null +++ b/apps/agent/README.md @@ -0,0 +1,32 @@ +# OCM ENGINE - AGENT + +Agent service is a wrapper around @ocm-engine/askar library. + +The agent can be started with two different mods - Rest and Consumer, default behaviour is a message consumer. + +Agent will consume messages from a broker (NATS) on a pre-configured stream and subjects. + +Then it will do execute the task and send result to the @ocm-engine/gateway. + +## Agent setup + +### From the root of the project run: + + +#### Install dependencies +``` +yarn install +``` +#### Copy .env.example to .env + +``` +cp .env.exampe .env +``` + +Do changes to the .env according to your needs. + +#### Start the agent locally: + +``` +yarn serve:agent +``` diff --git a/apps/agent/deployment/Dockerfile b/apps/agent/deployment/Dockerfile index 63745abbd85d9e6fe8adc0cc2fcbc0775694527c..bb1da9010cbabdc0c66fadc10fd7abb79b1732e7 100644 --- a/apps/agent/deployment/Dockerfile +++ b/apps/agent/deployment/Dockerfile @@ -9,7 +9,6 @@ COPY package.json yarn.lock ./ RUN yarn install - EXPOSE 8080 EXPOSE 8001 EXPOSE 6001 diff --git a/apps/agent/src/app/app.module.ts b/apps/agent/src/app/app.module.ts index 23d0bdb17340f5dd49270e9585eaa27d91164d82..151009b89202f89b0f40b53c1b89d64008b28c0e 100644 --- a/apps/agent/src/app/app.module.ts +++ b/apps/agent/src/app/app.module.ts @@ -1,6 +1,6 @@ import { Module } from "@nestjs/common"; -import { AskerDynamicModule } from "@ocm-engine/asker"; +import { AskarDynamicModule } from "@ocm-engine/askar"; import { ConfigModule } from "@nestjs/config"; import { agentConfig, @@ -23,7 +23,7 @@ const validationSchema = Joi.object({ @Module({ imports: [ - AskerDynamicModule.forRootAsync(), + AskarDynamicModule.forRootAsync(), ConfigModule.forRoot({ isGlobal: true, load: [agentConfig, ledgersConfig, natsConfig, gatewayConfig], diff --git a/apps/attestation-manager/README.md b/apps/attestation-manager/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6c241a740f8f35666c39eb1ee3cc417610553d42 --- /dev/null +++ b/apps/attestation-manager/README.md @@ -0,0 +1,28 @@ +# OCM ENGINE - Attestation Manager + +Internal service. + +Attestation manager accepts requests for schemas, credentials and messages. +That are coming from @ocm-engine/gateway api, then converts them to events and pushes to a NATS stream with specific for the event subject. + +## Attestation Manager setup + +### From the root of the project run: + +#### Install dependencies +``` +yarn install +``` +#### Copy .env.example to .env + +``` +cp .env.exampe .env +``` + +Do changes to the .env according to your needs. + +#### Start the agent locally: + +``` +yarn serve:am +``` diff --git a/apps/connection-manager/README.md b/apps/connection-manager/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e83281225e541ad1026cbc28ed27ccbf284d5a96 --- /dev/null +++ b/apps/connection-manager/README.md @@ -0,0 +1,27 @@ +# OCM ENGINE - Connection Manager + +Internal service. + +Connection manager accepts requests for connections, that are coming from @ocm-engine/gateway api, then converts them to events and pushes to a NATS stream with specific for the event subject. + +## Connection Manager setup + +### From the root of the project run: + +#### Install dependencies +``` +yarn install +``` +#### Copy .env.example to .env + +``` +cp .env.exampe .env +``` + +Do changes to the .env according to your needs. + +#### Start the agent locally: + +``` +yarn serve:cm +``` diff --git a/apps/gateway/README.md b/apps/gateway/README.md new file mode 100644 index 0000000000000000000000000000000000000000..74397ba439284f4806c26f0be84e0ecde61109bb --- /dev/null +++ b/apps/gateway/README.md @@ -0,0 +1,30 @@ +# OCM ENGINE - Gateway + +External service. + +This is the single point of communication, between Client and OCM. + +Gateway have a HTTP API described in gateway-swagger.json. It will accept all valid request and return a UUID. Then after the result is ready the gateway will push result object through websocket. Socket name can be configured according to usage. + + +## Attestation Manager setup + +### From the root of the project run: + +#### Install dependencies +``` +yarn install +``` +#### Copy .env.example to .env + +``` +cp .env.exampe .env +``` + +Do changes to the .env according to your needs. + +#### Start the agent locally: + +``` +yarn serve:gw +``` diff --git a/apps/gateway/src/app/managers/attestation.controller.ts b/apps/gateway/src/app/managers/attestation.controller.ts index 707c2ae23009b1820f1d8db7e45efda0433f6fca..88140a189570219c7d9f3fa5af5614d19f701ee5 100644 --- a/apps/gateway/src/app/managers/attestation.controller.ts +++ b/apps/gateway/src/app/managers/attestation.controller.ts @@ -46,15 +46,52 @@ export class AttestationController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ description: - "Error in sending data to connection manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.", - type: BadRequestException, + "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", + }, + }, + }, + }, + }, }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + @ApiBadRequestResponse({ + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Create schema", @@ -81,14 +118,54 @@ export class AttestationController { type: GatewayAcceptedResponseDto, }) @ApiBadRequestResponse({ - status: 400, - description: - "Error in sending data to connection manager. This error shows that attestation manager could not convert request to event or attestation manager could not send the event to the broker.", - type: BadRequestException, + 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", + }, + }, + }, + }, + }, }) @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Get schema by id", @@ -114,15 +191,27 @@ export class AttestationController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1234", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "List all schemas", @@ -149,14 +238,56 @@ export class AttestationController { type: GatewayAcceptedResponseDto, }) @ApiBadRequestResponse({ - status: 400, - 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.", - type: BadRequestException, + 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", + }, + }, + }, + }, + }, }) @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Create credential definition", @@ -185,14 +316,56 @@ export class AttestationController { type: GatewayAcceptedResponseDto, }) @ApiBadRequestResponse({ - status: 400, - 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.", - type: BadRequestException, + 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", + }, + }, + }, + }, + }, }) @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Issue credential", @@ -218,15 +391,27 @@ export class AttestationController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1234", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "List all credential", @@ -252,15 +437,27 @@ export class AttestationController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1234", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "List unaccepted credential offers", @@ -286,15 +483,27 @@ export class AttestationController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1234", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Accept credential offers", @@ -323,14 +532,56 @@ export class AttestationController { type: GatewayAcceptedResponseDto, }) @ApiBadRequestResponse({ - status: 400, - 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.", - type: BadRequestException, + 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", + }, + }, + }, + }, + }, }) @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Send basic message", diff --git a/apps/gateway/src/app/managers/connection.controller.ts b/apps/gateway/src/app/managers/connection.controller.ts index 6fd64d9afea73b55ee887ab25da785ec6dfca2ad..14f44d04e245918e30c3f2bc3c0dbef6be37e13e 100644 --- a/apps/gateway/src/app/managers/connection.controller.ts +++ b/apps/gateway/src/app/managers/connection.controller.ts @@ -37,15 +37,27 @@ export class ConnectionController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:4312", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Create invitation for connection", @@ -72,14 +84,54 @@ export class ConnectionController { type: GatewayAcceptedResponseDto, }) @ApiBadRequestResponse({ - status: 400, - 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.", - type: BadRequestException, + 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", + }, + }, + }, + }, + }, }) @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Accept invitation for connection", @@ -94,7 +146,7 @@ export class ConnectionController { return this.cmClient.sendPayload<CreateInvitationResponseDto>({ pattern: "connections", payload: { - source: "/invitation/accept", + source: "/invitations/accept", data: createInvitationDto, type: CONNECTION_ACCEPT, }, @@ -111,15 +163,27 @@ export class ConnectionController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:4312", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "List all connections", @@ -145,15 +209,27 @@ export class ConnectionController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:4312", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Get connection by id", diff --git a/apps/gateway/src/app/managers/proof.controller.ts b/apps/gateway/src/app/managers/proof.controller.ts index cc7f4e02f361f7e616f0ba5ba48661310509e155..8b5b1347f4ee5330ffb72ecded4789dc31b5a2a2 100644 --- a/apps/gateway/src/app/managers/proof.controller.ts +++ b/apps/gateway/src/app/managers/proof.controller.ts @@ -37,15 +37,27 @@ export class ProofController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1919", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "List received unaccepted proofs", @@ -72,14 +84,54 @@ export class ProofController { type: GatewayAcceptedResponseDto, }) @ApiBadRequestResponse({ - status: 400, - 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.", - type: BadRequestException, + 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", + }, + }, + }, + }, + }, }) @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + 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", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Issue proof for credential", @@ -105,15 +157,27 @@ export class ProofController { "Request is accepted for execution, the response id will match the event id received from the web socket", type: GatewayAcceptedResponseDto, }) - @ApiBadRequestResponse({ - status: 400, + @ApiInternalServerErrorResponse({ 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.", - type: BadRequestException, - }) - @ApiInternalServerErrorResponse({ - status: 500, - description: "Unknown error", + content: { + "application/json": { + schema: { + type: "object", + properties: { + statusCode: { + type: "number", + example: 500, + }, + + message: { + type: "string", + example: "connect ECONNREFUSED 0.0.0.0.0:1919", + }, + }, + }, + }, + }, }) @ApiOperation({ summary: "Accept credential proof", diff --git a/apps/gateway/src/main.ts b/apps/gateway/src/main.ts index 5f732fa024757a5d85ed1e44173fa822b3f37774..37b744b5ef6253acdda665b7b2002343930132c2 100644 --- a/apps/gateway/src/main.ts +++ b/apps/gateway/src/main.ts @@ -37,7 +37,7 @@ async function bootstrap() { app.enableShutdownHooks(); const config = new DocumentBuilder() - .setTitle("Gateway") + .setTitle("OCM Gateway") .setDescription("OCM ENGINE GATEWAY API") .setVersion("1.0") .addServer(`http://${gatewayConfig.host}:${gatewayConfig.httpPort}`) diff --git a/apps/proof-manager/README.md b/apps/proof-manager/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d363a69dbb4b090e67280d8d6e2bed71c88584d9 --- /dev/null +++ b/apps/proof-manager/README.md @@ -0,0 +1,27 @@ +# OCM ENGINE - Proof Manager + +Internal service. + +Connection manager accepts requests for proofs, that are coming from @ocm-engine/gateway api, then converts them to events and pushes to a NATS stream with specific for the event subject. + +## Proof Manager setup + +### From the root of the project run: + +#### Install dependencies +``` +yarn install +``` +#### Copy .env.example to .env + +``` +cp .env.exampe .env +``` + +Do changes to the .env according to your needs. + +#### Start the agent locally: + +``` +yarn serve:pm +``` diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index abf7679292621ae38c6de4292f6a5ddbcc710b92..3646983bfc3f4ac77a3889c748be603a60be8b8d 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -1,183 +1,238 @@ version: '3.8' services: - #===================== ISSUER =========================# - - agent-issuer: - labels: - - "traefik.http.routers.agent-issuer.rule=Host(`agent-issuer.local`)" - - "traefik.http.routers.agent-issuer.entrypoints=web" + gateway-issuer: profiles: - issuer - container_name: agent-issuer - build: - context: "../" - dockerfile: "./apps/agent/deployment/Dockerfile" + container_name: gw-issuer + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/gateway:/app/ + working_dir: /app + command: node main.js + ports: + - "8081:8081" + - "8881:8881" env_file: - ./env/issuer.env -# ports: -# - "8080:8080" -# - "8001:8001" depends_on: - pg_db: - condition: service_started - broker-issuer: + builder: + condition: service_completed_successfully + cm-issuer: condition: service_started - gateway-issuer: - labels: - - "traefik.http.routers.gateway-issuer.rule=Host(`gateway-issuer.local`)" - - "traefik.http.routers.gateway-issuer.entrypoints=web" + agent-issuer: profiles: - issuer - container_name: gateway-issuer - build: - context: "../" - dockerfile: "./apps/gateway/deployment/Dockerfile" + container_name: agent-issuer + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/agent:/app/ + working_dir: /app + command: node main.js + ports: + - "8080:8080" + - "8001:8001" env_file: - ./env/issuer.env -# ports: -# - "8081:8081" -# - "8881:8881" depends_on: + builder: + condition: service_completed_successfully cm-issuer: condition: service_started cm-issuer: - profiles: - - issuer container_name: cm-issuer - build: - context: "../" - dockerfile: "./apps/connection-manager/deployment/Dockerfile" + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/connection-manager:/app/ + working_dir: /app + command: node main.js + profiles: + - issuer env_file: - ./env/issuer.env ports: - "8882" depends_on: + builder: + condition: service_completed_successfully broker-issuer: condition: service_started am-issuer: + container_name: am-issuer + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/attestation-manager:/app/ + working_dir: /app + command: node main.js profiles: - issuer - container_name: am-issuer - build: - context: "../" - dockerfile: "./apps/attestation-manager/deployment/Dockerfile" env_file: - ./env/issuer.env ports: - "8883" depends_on: + builder: + condition: service_completed_successfully broker-issuer: condition: service_started + pm-issuer: + container_name: pm-issuer + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/proof-manager:/app/ + working_dir: /app + command: node main.js profiles: - issuer - container_name: pm-issuer - build: - context: "../" - dockerfile: "./apps/proof-manager/deployment/Dockerfile" env_file: - ./env/issuer.env ports: - "8884" depends_on: + builder: + condition: service_completed_successfully broker-issuer: condition: service_started #===================== holder =========================# - agent-holder: - labels: - - "traefik.http.routers.agent-issuer.rule=Host(`agent-holder.local`)" - - "traefik.http.routers.agent-issuer.entrypoints=web" + gateway-holder: profiles: - holder - container_name: agent-holder - build: - context: "../" - dockerfile: "./apps/agent/deployment/Dockerfile" + container_name: gw-holder + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/gateway:/app/ + working_dir: /app + command: node main.js + ports: + - "8091:8081" + - "8891:8881" env_file: - ./env/holder.env -# ports: -# - "8080:8080" -# - "8001:8001" depends_on: - pg_db: - condition: service_started - broker-holder: + builder: + condition: service_completed_successfully + cm-issuer: condition: service_started - gateway-holder: - labels: - - "traefik.http.routers.gateway-issuer.rule=Host(`gateway-holder.local`)" - - "traefik.http.routers.gateway-issuer.entrypoints=web" + agent-holder: profiles: - holder - container_name: gateway-holder - build: - context: "../" - dockerfile: "./apps/gateway/deployment/Dockerfile" + container_name: agent-holder + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/agent:/app/ + working_dir: /app + command: node main.js + ports: + - "8090:8080" + - "6001:6001" env_file: - ./env/holder.env -# ports: -# - "8081:8081" -# - "8881:8881" depends_on: - cm-holder: + builder: + condition: service_completed_successfully + cm-issuer: condition: service_started cm-holder: + container_name: cm-holder + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/connection-manager:/app/ + working_dir: /app + command: node main.js profiles: - holder - container_name: cm-holder - build: - context: "../" - dockerfile: "./apps/connection-manager/deployment/Dockerfile" env_file: - ./env/holder.env ports: - "8882" depends_on: - broker-holder: + builder: + condition: service_completed_successfully + broker-issuer: condition: service_started am-holder: + container_name: am-holder + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/attestation-manager:/app/ + working_dir: /app + command: node main.js profiles: - holder - container_name: am-holder - build: - context: "../" - dockerfile: "./apps/attestation-manager/deployment/Dockerfile" env_file: - ./env/holder.env ports: - "8883" depends_on: - broker-holder: + builder: + condition: service_completed_successfully + broker-issuer: condition: service_started + pm-holder: + container_name: pm-holder + image: node:18.16.0 + volumes: + - ./data/node_modules:/app/node_modules + - ./data/dist/apps/proof-manager:/app/ + working_dir: /app + command: node main.js profiles: - holder - container_name: pm-holder - build: - context: "../" - dockerfile: "./apps/proof-manager/deployment/Dockerfile" env_file: - ./env/holder.env ports: - "8884" depends_on: - broker-holder: + builder: + condition: service_completed_successfully + broker-issuer: condition: service_started - #===================== INFRA =========================# + 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:all + exit 0 pg_db: image: 'postgres:latest' @@ -201,7 +256,6 @@ services: volumes: - ./data/issuer/nats/:/data/ - broker-holder: profiles: - holder @@ -214,16 +268,3 @@ services: volumes: - ./data/holder/nats/:/data/ - reverse-proxy: - image: traefik:v2.10.1 - command: - - "--api.insecure=true" - - "--providers.docker=true" - - "--entrypoints.web.address=:80" - - "--entrypoints.webextra.address=:8001" - ports: - - "80:80" - - "8001:8001" - - "8080:8080" - volumes: - - ./data/var/run/docker.sock:/var/run/docker.sock diff --git a/compose/env/holder.env b/compose/env/holder.env index b5be92bcc0e72363f3a9b9102873ebc8b1dd63e8..c395fb460c8420b9007cef1380c34840040844ef 100644 --- a/compose/env/holder.env +++ b/compose/env/holder.env @@ -1,10 +1,10 @@ LEDGERS="BCOVRIN_TEST" IDUNION_KEY= -AGENT_PEER_URL="http://agent-holder:8001" -AGENT_NAME=DEV_AGENT_HOLDER_OCM # this should be changed to company name -AGENT_KEY=HwNJroKHTSSj3XvE7ZAnuKiTn2C4QkFvxEqfm5rzhNrh #example random string -AGENT_DID_SEED=200000000000000000000000TCuste21 #did private key seed min lenght 32 +AGENT_PEER_URL="http://agent-holder:6001" +AGENT_NAME=DEV_AGENT_HOLDER_OCM_4 # this should be changed to company name +AGENT_KEY=DEV_AGENT_HOLDER_OCM_4 #example random string +AGENT_DID_SEED=2000000000000000CCA120000000TCuste21jsjs #did private key seed min lenght 32 AGENT_DB_HOST=pg_db:5432 AGENT_DB_USER=postgres AGENT_DB_PASS=postgres @@ -16,7 +16,7 @@ AGENT_RETE_LIMIT=5 NATS_SERVERS=broker-holder:4222 NATS_STREAM_NAME=ssi_holder_stream -NATS_SUBJECTS="connections.*,proofs.*,credentials.*,schemas.*" +NATS_SUBJECTS="connections.*,proofs.*,credentials.*,schemas.*,messages.*" GATEWAY_HTTP_PORT=8081 GATEWAY_TCP_PORT=8881 @@ -28,7 +28,7 @@ CONNECTION_SERVICE_TCP_PORT=8882 CONNECTION_SERVICE_HOST=cm-holder ATTESTATION_SERVICE_TCP_PORT=8883 -ATTESTATION_SERVICE_HOST=ap-holder +ATTESTATION_SERVICE_HOST=am-holder PROOF_SERVICE_TCP_PORT=8884 PROOF_SERVICE_HOST=pm-holder diff --git a/compose/env/issuer.env b/compose/env/issuer.env index 9fb7f25f5fc4d7d4dbd5da2728b1468333f2848a..d3774abdcc0cab97012a7a3950a5ea20c4467c82 100644 --- a/compose/env/issuer.env +++ b/compose/env/issuer.env @@ -2,9 +2,9 @@ LEDGERS="BCOVRIN_TEST" IDUNION_KEY= AGENT_PEER_URL="http://agent-issuer:8001" -AGENT_NAME=DEV_AGENT_ISSUER_OCM # this should be changed to company name -AGENT_KEY=HwNJroKHTSSj3XvE7ZAnuKiTn2C4QkFvxEqfm5rzhNrh #example random string -AGENT_DID_SEED=200000000000000000000000TCuste21 #did private key seed min lenght 32 +AGENT_NAME=DEV_AGENT_ISSUER_OCM_4 # this should be changed to company name +AGENT_KEY=DEV_AGENT_ISSUER_OCM_4 #example random string +AGENT_DID_SEED=20000000000000000000000aca0xxaDTCuste21udhasjs #did private key seed min lenght 32 AGENT_DB_HOST=pg_db:5432 AGENT_DB_USER=postgres AGENT_DB_PASS=postgres @@ -16,7 +16,7 @@ AGENT_RETE_LIMIT=5 NATS_SERVERS=broker-issuer:4222 NATS_STREAM_NAME=ssi_issuer_stream -NATS_SUBJECTS="connections.*,proofs.*,credentials.*,schemas.*" +NATS_SUBJECTS="connections.*,proofs.*,credentials.*,credentials.definition.*,credentials.offer.*,schemas.*,messages.*" GATEWAY_HTTP_PORT=8081 GATEWAY_TCP_PORT=8881 @@ -28,7 +28,7 @@ CONNECTION_SERVICE_TCP_PORT=8882 CONNECTION_SERVICE_HOST=cm-issuer ATTESTATION_SERVICE_TCP_PORT=8883 -ATTESTATION_SERVICE_HOST=ap-issuer +ATTESTATION_SERVICE_HOST=am-issuer PROOF_SERVICE_TCP_PORT=8884 PROOF_SERVICE_HOST=pm-issuer diff --git a/gateway-swagger.json b/gateway-swagger.json index 2c80f9140e94b31c739be461eb9efbe49a070d93..0da4211542ced768ce3d3628b3b896e7011415af 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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":"Error in sending data to connection 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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}},"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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":"Error in sending data to connection 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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":""},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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":"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}},"/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"}}}},"400":{"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":{"$ref":"#/components/schemas/BadRequestException"}}}},"500":{"description":"Unknown error"}}}}},"info":{"title":"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"]},"BadRequestException":{"type":"object","properties":{}},"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"},"credentialDefinitionId":{"type":"string"},"attributes":{"type":"array","items":{"$ref":"#/components/schemas/IssueCredentialAttributes"}}},"required":["connectionId","credentialDefinitionId","attributes"]},"IssueProofAttribute":{"type":"object","properties":{"attributeName":{"type":"string"},"credentialDefinitionId":{"type":"string"},"schemaId":{"type":"string"}},"required":["attributeName","credentialDefinitionId","schemaId"]},"IssueProofRequestDto":{"type":"object","properties":{"connectionId":{"type":"string"},"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/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 diff --git a/libs/asker/.eslintrc.json b/libs/askar/.eslintrc.json similarity index 100% rename from libs/asker/.eslintrc.json rename to libs/askar/.eslintrc.json diff --git a/libs/askar/README.md b/libs/askar/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9aba309fee8ea38852c69ba9c8b4b22090af9b65 --- /dev/null +++ b/libs/askar/README.md @@ -0,0 +1,11 @@ +# Askar + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build askar` to build the library. + +## Running unit tests + +Run `nx test askar` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/asker/jest.config.ts b/libs/askar/jest.config.ts similarity index 76% rename from libs/asker/jest.config.ts rename to libs/askar/jest.config.ts index 64e0c4903a577ac1debbeaf08db1d0498afc06cd..ac304c505f27781865cf6ab6ef0ac029ac4474b1 100644 --- a/libs/asker/jest.config.ts +++ b/libs/askar/jest.config.ts @@ -1,11 +1,11 @@ /* eslint-disable */ export default { - displayName: "asker", + displayName: "askar", preset: "../../jest.preset.js", testEnvironment: "node", transform: { "^.+\\.[tj]s$": ["ts-jest", { tsconfig: "<rootDir>/tsconfig.spec.json" }], }, moduleFileExtensions: ["ts", "js", "html"], - coverageDirectory: "../../coverage/libs/asker", + coverageDirectory: "../../coverage/libs/askar", }; diff --git a/libs/asker/package.json b/libs/askar/package.json similarity index 60% rename from libs/asker/package.json rename to libs/askar/package.json index 1dbe2d3efbed4a05a02c5263b9287b6a486e852e..4dbed996bb239ccf2366ec47c52f900c9d4f05d2 100644 --- a/libs/asker/package.json +++ b/libs/askar/package.json @@ -1,5 +1,5 @@ { - "name": "@ocm-engine/asker", + "name": "@ocm-engine/askar", "version": "0.0.1", "type": "commonjs" } diff --git a/libs/asker/project.json b/libs/askar/project.json similarity index 64% rename from libs/asker/project.json rename to libs/askar/project.json index 81aa5d1a6d48105ff741c32fb0fa993a22386655..18ee7241cf7d6a0728e1301a92f3b4eaae642d91 100644 --- a/libs/asker/project.json +++ b/libs/askar/project.json @@ -1,32 +1,32 @@ { - "name": "asker", + "name": "askar", "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/asker/src", + "sourceRoot": "libs/askar/src", "projectType": "library", "targets": { "build": { "executor": "@nx/js:tsc", "outputs": ["{options.outputPath}"], "options": { - "outputPath": "dist/libs/asker", - "tsConfig": "libs/asker/tsconfig.lib.json", - "packageJson": "libs/asker/package.json", - "main": "libs/asker/src/index.ts", - "assets": ["libs/asker/*.md"] + "outputPath": "dist/libs/askar", + "tsConfig": "libs/askar/tsconfig.lib.json", + "packageJson": "libs/askar/package.json", + "main": "libs/askar/src/index.ts", + "assets": ["libs/askar/*.md"] } }, "lint": { "executor": "@nx/linter:eslint", "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": ["libs/asker/**/*.ts"] + "lintFilePatterns": ["libs/askar/**/*.ts"] } }, "test": { "executor": "@nx/jest:jest", "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "libs/asker/jest.config.ts", + "jestConfig": "libs/askar/jest.config.ts", "passWithNoTests": true }, "configurations": { diff --git a/libs/asker/src/agent.utils.ts b/libs/askar/src/agent.utils.ts similarity index 100% rename from libs/asker/src/agent.utils.ts rename to libs/askar/src/agent.utils.ts diff --git a/libs/askar/src/askar-nats/agent.consumer.service.ts b/libs/askar/src/askar-nats/agent.consumer.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..afa0028c2c9e57ef6a259bba3d0de1f48f97a5a1 --- /dev/null +++ b/libs/askar/src/askar-nats/agent.consumer.service.ts @@ -0,0 +1,58 @@ +import { + Injectable, + Logger, + OnModuleDestroy, + OnModuleInit, +} from "@nestjs/common"; +import { AgentService } from "../askar/agent.service"; +import { ConsumerService } from "@ocm-engine/nats"; +import { ConfigService } from "@nestjs/config"; +import { IConfAgent } from "@ocm-engine/config"; +import { GatewayClient } from "@ocm-engine/clients"; +import { EventHandlerService } from "./event.handler.service"; + +@Injectable() +export class AgentConsumerService implements OnModuleInit, OnModuleDestroy { + private readonly logger = new Logger(AgentConsumerService.name); + constructor( + private readonly agentService: AgentService, + private readonly consumerService: ConsumerService, + private readonly configService: ConfigService, + private readonly gatewayClient: GatewayClient, + private readonly eventHandlerService: EventHandlerService, + ) {} + + async onModuleInit(): Promise<void> { + const config = this.configService.get<IConfAgent>("agent"); + + if (config?.agentIsRest) { + this.logger.log( + "Agent is configured as rest, there is no need for consumer!", + ); + return; + } + + await this.consumerService.subscribe(async (event) => { + this.logger.debug(JSON.stringify(event, null, 2)); + let ev; + + try { + ev = await this.eventHandlerService.handle<typeof event.data>(event); + this.logger.debug(JSON.stringify(ev)); + } catch (e) { + this.logger.debug({ e: JSON.stringify(e, null, 2) }); + event.data = e; + ev = event; + } + + this.gatewayClient.sendPayload(ev); + + return; + }); + } + + async onModuleDestroy(): Promise<void> { + this.logger.log("disconnecting from broker"); + await this.consumerService.disconnect(); + } +} diff --git a/libs/asker/src/asker-nats/asker.nats.module.ts b/libs/askar/src/askar-nats/askar.nats.module.ts similarity index 78% rename from libs/asker/src/asker-nats/asker.nats.module.ts rename to libs/askar/src/askar-nats/askar.nats.module.ts index ce0b12d9c1155cd2d99ff0938d1f6c24cd41c1b7..bf6bc7af41ecac01c32c6461a6974c162e13a223 100644 --- a/libs/asker/src/asker-nats/asker.nats.module.ts +++ b/libs/askar/src/askar-nats/askar.nats.module.ts @@ -3,9 +3,10 @@ import { ConfigModule } from "@nestjs/config"; import { LedgersModule } from "@ocm-engine/ledgers"; import { APP_PIPE } from "@nestjs/core"; import { AgentConsumerService } from "./agent.consumer.service"; -import { AgentService } from "../asker/agent.service"; +import { AgentService } from "../askar/agent.service"; import { ConsumerService } from "@ocm-engine/nats"; import { GatewayClient } from "@ocm-engine/clients"; +import { EventHandlerService } from "./event.handler.service"; @Module({ imports: [ConfigModule, LedgersModule], @@ -14,6 +15,7 @@ import { GatewayClient } from "@ocm-engine/clients"; AgentConsumerService, AgentService, GatewayClient, + EventHandlerService, { provide: APP_PIPE, useValue: new ValidationPipe({ @@ -23,4 +25,4 @@ import { GatewayClient } from "@ocm-engine/clients"; ], controllers: [], }) -export class AskerNatsModule {} +export class AskarNatsModule {} diff --git a/libs/askar/src/askar-nats/event.handler.service.ts b/libs/askar/src/askar-nats/event.handler.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..0561068736ff1ec96d3331c210a49683aaa24096 --- /dev/null +++ b/libs/askar/src/askar-nats/event.handler.service.ts @@ -0,0 +1,133 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { AgentService } from "../askar/agent.service"; +import { + AcceptCredentialOfferRequestDto, + AcceptProofRequestDto, + CloudEventDto, + CONNECTION_ACCEPT, + CONNECTION_CREATE, + CONNECTION_GET, + CONNECTION_LIST, + CreateCredentialDefinitionRequsetDto, + CreateInvitationResponseDto, + CreateSchemaRequestDto, + CRED_DEF_CREATE, + CRED_ISSUE, + CRED_LIST, + CRED_OFFER_ACCEPT, + CRED_OFFER_LIST, + GetConnectionRequestDto, + GetSchemaRequestDto, + IssueCredentialRequestDto, + IssueProofRequestDto, + MakeBasicMessageRequestDto, + MESSAGE_MAKE, + PROOF_ACCEPT, + PROOF_ISSUE, + PROOF_LIST, + SCHEMA_CREATE, + SCHEMA_GET, + SCHEMA_LIST, +} from "@ocm-engine/dtos"; +import asyncRetry from "async-retry"; + +@Injectable() +export class EventHandlerService { + private readonly logger = new Logger(EventHandlerService.name); + + constructor(private readonly agentService: AgentService) {} + + async handle<T>(event: CloudEventDto<T>) { + let data; + let dto; + await asyncRetry( + async () => { + switch (event.type) { + case CONNECTION_CREATE: + data = await this.agentService.createInvitation(); + break; + case CONNECTION_ACCEPT: + dto = event.data as CreateInvitationResponseDto; + data = await this.agentService.acceptInvitation(dto.invitationUrl); + break; + + case CONNECTION_LIST: + data = await this.agentService.fetchConnections(); + break; + + case CONNECTION_GET: + dto = event.data as GetConnectionRequestDto; + data = await this.agentService.getConnectionById(dto.connectionId); + break; + + case SCHEMA_CREATE: + dto = event.data as CreateSchemaRequestDto; + data = await this.agentService.createSchema(dto); + break; + case SCHEMA_LIST: + data = await this.agentService.fetchSchemas(); + break; + + case SCHEMA_GET: + dto = event.data as GetSchemaRequestDto; + data = await this.agentService.getSchemaById(dto.schemaId); + break; + case CRED_DEF_CREATE: + data = await this.agentService.createCredentialDefinition( + event.data as CreateCredentialDefinitionRequsetDto, + ); + break; + + case CRED_ISSUE: + data = await this.agentService.issueCredential( + event.data as IssueCredentialRequestDto, + ); + break; + + case CRED_LIST: + data = await this.agentService.credentials(); + break; + + case CRED_OFFER_LIST: + data = await this.agentService.credentialByStatedOfferReceived(); + break; + + case CRED_OFFER_ACCEPT: + dto = event.data as AcceptCredentialOfferRequestDto; + data = await this.agentService.acceptCredential( + dto.credentialRecordId, + ); + break; + + case PROOF_ISSUE: + dto = event.data as IssueProofRequestDto; + data = await this.agentService.issueProof(dto); + break; + + case PROOF_LIST: + data = await this.agentService.proofs(); + break; + + case PROOF_ACCEPT: + dto = event.data as AcceptProofRequestDto; + data = await this.agentService.acceptProof(dto.proofRecordId); + break; + + case MESSAGE_MAKE: + dto = event.data as MakeBasicMessageRequestDto; + data = await this.agentService.sendMessage(dto); + break; + } + }, + { + retries: 5, + onRetry: (error: unknown) => { + this.logger.log(JSON.stringify(error, null, 2)); + }, + }, + ); + + event.data = data; + return event; + } +} diff --git a/libs/asker/src/asker-rest/asker.rest.module.ts b/libs/askar/src/askar-rest/askar.rest.module.ts similarity index 84% rename from libs/asker/src/asker-rest/asker.rest.module.ts rename to libs/askar/src/askar-rest/askar.rest.module.ts index 6d49616a939deb3abd6de188fe823a23e4efa506..7390822ad25c59d12e428ba08264ddc9bd9cee82 100644 --- a/libs/asker/src/asker-rest/asker.rest.module.ts +++ b/libs/askar/src/askar-rest/askar.rest.module.ts @@ -1,5 +1,5 @@ import { Module, ValidationPipe } from "@nestjs/common"; -import { AgentService } from "../asker/agent.service"; +import { AgentService } from "../askar/agent.service"; import { ConfigModule } from "@nestjs/config"; import { LedgersModule } from "@ocm-engine/ledgers"; import { APP_PIPE } from "@nestjs/core"; @@ -18,4 +18,4 @@ import { RestController } from "./rest.controller"; ], controllers: [RestController], }) -export class AskerRestModule {} +export class AskarRestModule {} diff --git a/libs/asker/src/asker-rest/exception.handler.ts b/libs/askar/src/askar-rest/exception.handler.ts similarity index 100% rename from libs/asker/src/asker-rest/exception.handler.ts rename to libs/askar/src/askar-rest/exception.handler.ts diff --git a/libs/asker/src/asker-rest/rest.controller.ts b/libs/askar/src/askar-rest/rest.controller.ts similarity index 97% rename from libs/asker/src/asker-rest/rest.controller.ts rename to libs/askar/src/askar-rest/rest.controller.ts index f4b3aafbf14d5b1c76e4d6d97220b7ac2e6d7e6d..e0d3b06e1e4e5c302dc973c559b3fcbb6e1d99d7 100644 --- a/libs/asker/src/asker-rest/rest.controller.ts +++ b/libs/askar/src/askar-rest/rest.controller.ts @@ -1,5 +1,5 @@ import { Body, Controller, Get, Param, Post, UseFilters } from "@nestjs/common"; -import { AgentService } from "../asker/agent.service"; +import { AgentService } from "../askar/agent.service"; import { CreateCredentialDefinitionRequsetDto, CreateInvitationResponseDto, diff --git a/libs/askar/src/askar.dynamic.module.ts b/libs/askar/src/askar.dynamic.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..1bb4e507aae6c9853a6a2a2193f5a50be84cffeb --- /dev/null +++ b/libs/askar/src/askar.dynamic.module.ts @@ -0,0 +1,21 @@ +import { DynamicModule, Module } from "@nestjs/common"; +import { ConfigModule } from "@nestjs/config"; +import { AskarRestModule } from "./askar-rest/askar.rest.module"; +import { AskarNatsModule } from "./askar-nats/askar.nats.module"; +import { AskarModule } from "./askar/askar.module"; +import * as process from "process"; + +@Module({}) +export class AskarDynamicModule { + static forRootAsync(): DynamicModule { + const isRest = process.env["AGENT_IS_REST"] === "true"; + + const module = isRest ? AskarRestModule : AskarNatsModule; + + return { + module: AskarDynamicModule, + imports: [ConfigModule, AskarModule, module], + providers: [module], + }; + } +} diff --git a/libs/asker/src/asker/agent.event.listener.servce.ts b/libs/askar/src/askar/agent.event.listener.servce.ts similarity index 82% rename from libs/asker/src/asker/agent.event.listener.servce.ts rename to libs/askar/src/askar/agent.event.listener.servce.ts index 8b9a0f56b1d3a4d4db4236f92415f1743ca8c440..03eaf71d0507327cd89e83b680ae4cdfbcf21cf5 100644 --- a/libs/asker/src/asker/agent.event.listener.servce.ts +++ b/libs/askar/src/askar/agent.event.listener.servce.ts @@ -1,6 +1,6 @@ import { Injectable, Logger, OnModuleInit } from "@nestjs/common"; import { GatewayClient } from "@ocm-engine/clients"; -import { AskerService } from "./asker.service"; +import { AskarService } from "./askar.service"; import { BasicMessageEventTypes, BasicMessageRole, @@ -21,7 +21,7 @@ export class AgentEventListenerServce implements OnModuleInit { constructor( private readonly gatewayClient: GatewayClient, - private readonly asker: AskerService, + private readonly askar: AskarService, private readonly configService: ConfigService, ) {} @@ -30,15 +30,21 @@ export class AgentEventListenerServce implements OnModuleInit { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.agentConfig = this.configService.get<IConfAgent>("agent")!; - this.asker.agent.events.on( + this.askar.agent.events.on( BasicMessageEventTypes.BasicMessageStateChanged, async (ev: BasicMessageStateChangedEvent) => { if (ev.payload.basicMessageRecord.role === BasicMessageRole.Receiver) { this.logger.debug(JSON.stringify(ev, null, 2)); + const connectionInfo = await this.askar.agent.connections.findById( + ev.payload.basicMessageRecord.connectionId, + ); + const dto = new MakeBasicMessageResponseDto(); dto.message = ev.payload.basicMessageRecord.content; dto.id = ev.payload.basicMessageRecord.id; + dto.connectionId = ev.payload.basicMessageRecord.connectionId; + dto.from = connectionInfo?.theirLabel; if (this.agentConfig.agentIsRest) { this.logger.debug( diff --git a/libs/asker/src/asker/agent.service.ts b/libs/askar/src/askar/agent.service.ts similarity index 71% rename from libs/asker/src/asker/agent.service.ts rename to libs/askar/src/askar/agent.service.ts index 0fdf814a67efdccd8e78c12bab2dff06ee966a44..27fe92a7a1291e7fe9257731ce0f3cd8aea0a9f4 100644 --- a/libs/asker/src/asker/agent.service.ts +++ b/libs/askar/src/askar/agent.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@nestjs/common"; -import { AskerService } from "./asker.service"; +import { AskarService } from "./askar.service"; import { AcceptInvitationResponseDto, ConnectionNotFoundError, @@ -26,14 +26,14 @@ import { AnonCredsRequestedAttribute } from "@aries-framework/anoncreds"; @Injectable() export class AgentService { - constructor(private readonly asker: AskerService) {} + constructor(private readonly askar: AskarService) {} createInvitation = async () => { - const outOfBoundRecord = await this.asker.agent.oob.createInvitation(); + const outOfBoundRecord = await this.askar.agent.oob.createInvitation(); const i = new CreateInvitationResponseDto(); i.invitationUrl = outOfBoundRecord.outOfBandInvitation.toUrl({ - domain: this.asker.agentConfig.agentPeerAddress, + domain: this.askar.agentConfig.agentPeerAddress, }); return i; @@ -41,14 +41,15 @@ export class AgentService { acceptInvitation = async (invitationUrl: string) => { const { connectionRecord } = - await this.asker.agent.oob.receiveInvitationFromUrl(invitationUrl); + await this.askar.agent.oob.receiveInvitationFromUrl(invitationUrl); if (typeof connectionRecord === "undefined") { throw new ConnectionNotFoundError(); } const r = new AcceptInvitationResponseDto(); - r.id = connectionRecord.id; + r.connectionName = connectionRecord.theirLabel; + r.connectionId = connectionRecord.id; r.did = connectionRecord.did; r.invitationDid = connectionRecord.invitationDid; r.outOfBandId = connectionRecord.outOfBandId; @@ -58,26 +59,26 @@ export class AgentService { }; fetchConnections() { - return this.asker.agent.connections.getAll(); + return this.askar.agent.connections.getAll(); } getConnectionById = (id: string) => { - return this.asker.agent.connections.findById(id); + return this.askar.agent.connections.findById(id); }; fetchSchemas = () => { - return this.asker.agent.modules.anoncreds.getCreatedSchemas({}); + return this.askar.agent.modules.anoncreds.getCreatedSchemas({}); }; getSchemaById = (schemaId: string) => { - return this.asker.agent.modules.anoncreds.getSchema(schemaId); + return this.askar.agent.modules.anoncreds.getSchema(schemaId); }; createSchema = async (schema: CreateSchemaRequestDto) => { - const dids = await this.asker.agent.dids.getCreatedDids({ method: "indy" }); + const dids = await this.askar.agent.dids.getCreatedDids({ method: "indy" }); const schemaResult = - await this.asker.agent.modules.anoncreds.registerSchema({ + await this.askar.agent.modules.anoncreds.registerSchema({ schema: { name: schema.name, issuerId: dids[0].did, @@ -105,10 +106,10 @@ export class AgentService { createCredentialDefinition = async ( credentialDefinitionDto: CreateCredentialDefinitionRequsetDto, ) => { - const dids = await this.asker.agent.dids.getCreatedDids({ method: "indy" }); + const dids = await this.askar.agent.dids.getCreatedDids({ method: "indy" }); const credDef = - await this.asker.agent.modules.anoncreds.registerCredentialDefinition({ + await this.askar.agent.modules.anoncreds.registerCredentialDefinition({ credentialDefinition: { tag: credentialDefinitionDto.tag, issuerId: dids[0].did, @@ -134,37 +135,48 @@ export class AgentService { }; issueCredential = async (issueCredentialDto: IssueCredentialRequestDto) => { - const credentialExchangeRecord = - await this.asker.agent.credentials.offerCredential({ - protocolVersion: "v2", - connectionId: issueCredentialDto.connectionId, - credentialFormats: { - anoncreds: { - credentialDefinitionId: issueCredentialDto.credentialDefinitionId, - attributes: issueCredentialDto.attributes, + console.log("tuk sym", JSON.stringify(issueCredentialDto, null, 2)); + try { + const credentialExchangeRecord = + await this.askar.agent.credentials.offerCredential({ + protocolVersion: "v2", + connectionId: issueCredentialDto.connectionId, + credentialFormats: { + anoncreds: { + credentialDefinitionId: issueCredentialDto.credentialDefinitionId, + attributes: issueCredentialDto.attributes, + }, }, - }, - }); - - const response = new IssueCredentialResponseDto(); - response.credentialId = credentialExchangeRecord.id; - response.connectionId = credentialExchangeRecord.connectionId; - response.attributes = credentialExchangeRecord.credentialAttributes; - response.createdAt = credentialExchangeRecord.createdAt; - - return response; + }); + console.log("ISSUER CREDENTIAL"); + console.log(JSON.stringify(credentialExchangeRecord, null, 2)); + console.log("issue credential end"); + + const response = new IssueCredentialResponseDto(); + response.credentialId = credentialExchangeRecord.id; + response.connectionId = credentialExchangeRecord.connectionId; + response.attributes = credentialExchangeRecord.credentialAttributes; + response.createdAt = credentialExchangeRecord.createdAt; + + return response; + } catch (e) { + console.log("------------------------"); + console.log(JSON.stringify(e, null, 2)); + console.log("------------------------"); + throw new Error("unknown"); + } }; acceptCredential = async (credentialRecordId: string) => { const linkSecretIds = - await this.asker.agent.modules.anoncreds.getLinkSecretIds(); + await this.askar.agent.modules.anoncreds.getLinkSecretIds(); if (linkSecretIds.length === 0) { - await this.asker.agent.modules.anoncreds.createLinkSecret(); + await this.askar.agent.modules.anoncreds.createLinkSecret(); } const credentialExchangeRecord = - await this.asker.agent.credentials.acceptOffer({ + await this.askar.agent.credentials.acceptOffer({ credentialRecordId, }); @@ -178,7 +190,7 @@ export class AgentService { }; credentials = async () => { - const credentials = await this.asker.agent.credentials.findAllByQuery({ + const credentials = await this.askar.agent.credentials.findAllByQuery({ state: CredentialState.Done, }); @@ -196,7 +208,7 @@ export class AgentService { }; credentialByStatedOfferReceived = async () => { - const offers = await this.asker.agent.credentials.findAllByQuery({ + const offers = await this.askar.agent.credentials.findAllByQuery({ state: CredentialState.OfferReceived, }); @@ -231,7 +243,7 @@ export class AgentService { } if (!issueProofDto.connectionId) { - const { proofRecord } = await this.asker.agent.proofs.createRequest({ + const { proofRecord } = await this.askar.agent.proofs.createRequest({ protocolVersion: "v2", proofFormats: { anoncreds: { @@ -244,7 +256,7 @@ export class AgentService { exchangeRecord = proofRecord; } else { - exchangeRecord = await this.asker.agent.proofs.requestProof({ + exchangeRecord = await this.askar.agent.proofs.requestProof({ protocolVersion: "v2", connectionId: issueProofDto.connectionId, proofFormats: { @@ -268,7 +280,7 @@ export class AgentService { }; proofs = async () => { - const proofs = await this.asker.agent.proofs.findAllByQuery({ + const proofs = await this.askar.agent.proofs.findAllByQuery({ state: ProofState.RequestReceived, }); @@ -289,11 +301,11 @@ export class AgentService { acceptProof = async (proofRecordId: string) => { const requestedCredentials = - await this.asker.agent.proofs.selectCredentialsForRequest({ + await this.askar.agent.proofs.selectCredentialsForRequest({ proofRecordId, }); - const proof = await this.asker.agent.proofs.acceptRequest({ + const proof = await this.askar.agent.proofs.acceptRequest({ proofRecordId, proofFormats: requestedCredentials.proofFormats, }); @@ -309,17 +321,21 @@ export class AgentService { }; resolve = async (did: string) => { - return this.asker.agent.dids.resolve(did); + return this.askar.agent.dids.resolve(did); }; sendMessage = async (message: MakeBasicMessageRequestDto) => { const response = new MakeBasicMessageResponseDto(); - const m = await this.asker.agent.basicMessages.sendMessage( + const m = await this.askar.agent.basicMessages.sendMessage( message.connectionId, message.message, ); + const connectionInfo = await this.getConnectionById(message.connectionId); + + response.connectionId = m.connectionId; + response.to = connectionInfo?.theirLabel || ""; response.id = m.id; response.message = m.content; diff --git a/libs/asker/src/asker/asker.module.ts b/libs/askar/src/askar/askar.module.ts similarity index 55% rename from libs/asker/src/asker/asker.module.ts rename to libs/askar/src/askar/askar.module.ts index 90dea64021e9cd55b7559b30fc5c88113255667b..05a8706a87d787f04c2509461d5db4e9463974e0 100644 --- a/libs/asker/src/asker/asker.module.ts +++ b/libs/askar/src/askar/askar.module.ts @@ -1,14 +1,20 @@ import { Module, Global } from "@nestjs/common"; -import { AskerService } from "./asker.service"; +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 { GatewayClient } from "@ocm-engine/clients"; @Global() @Module({ imports: [ConfigModule, LedgersModule], - providers: [AgentService, AskerService, AgentEventListenerServce], - exports: [AgentService, AskerService], + providers: [ + AgentService, + AskarService, + AgentEventListenerServce, + GatewayClient, + ], + exports: [AgentService, AskarService], }) -export class AskerModule {} +export class AskarModule {} diff --git a/libs/asker/src/asker/asker.service.ts b/libs/askar/src/askar/askar.service.ts similarity index 96% rename from libs/asker/src/asker/asker.service.ts rename to libs/askar/src/askar/askar.service.ts index b3a391c08c9b91c044d01b19f52bd3694ccc8be9..e07eb52a9f77a1f1b57ff7e0df2acdeebf9ec5e8 100644 --- a/libs/asker/src/asker/asker.service.ts +++ b/libs/askar/src/askar/askar.service.ts @@ -26,10 +26,10 @@ import { import { IConfAgent } from "@ocm-engine/config"; @Injectable() -export class AskerService implements OnModuleInit, OnModuleDestroy { +export class AskarService implements OnModuleInit, OnModuleDestroy { public agent: Agent<ReturnType<typeof getAskarAnonCredsIndyModules>>; public agentConfig: IConfAgent; - private readonly logger: Logger = new Logger(AskerService.name); + private readonly logger: Logger = new Logger(AskarService.name); constructor( private readonly configService: ConfigService, diff --git a/libs/askar/src/index.ts b/libs/askar/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..5fb756c0f59cf5403e52175ae5134ced9232a5ea --- /dev/null +++ b/libs/askar/src/index.ts @@ -0,0 +1,5 @@ +export * from "./askar/askar.module"; +export * from "./askar/agent.service"; +export * from "./askar/askar.service"; +export * from "./askar.dynamic.module"; +export * from "./askar-rest/askar.rest.module"; diff --git a/libs/asker/tsconfig.json b/libs/askar/tsconfig.json similarity index 100% rename from libs/asker/tsconfig.json rename to libs/askar/tsconfig.json diff --git a/libs/asker/tsconfig.lib.json b/libs/askar/tsconfig.lib.json similarity index 100% rename from libs/asker/tsconfig.lib.json rename to libs/askar/tsconfig.lib.json diff --git a/libs/asker/tsconfig.spec.json b/libs/askar/tsconfig.spec.json similarity index 100% rename from libs/asker/tsconfig.spec.json rename to libs/askar/tsconfig.spec.json diff --git a/libs/asker/README.md b/libs/asker/README.md deleted file mode 100644 index 50086f54e1b6a81501d15fbe066128e52568513b..0000000000000000000000000000000000000000 --- a/libs/asker/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# asker - -This library was generated with [Nx](https://nx.dev). - -## Building - -Run `nx build asker` to build the library. - -## Running unit tests - -Run `nx test asker` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/asker/src/asker-nats/agent.consumer.service.ts b/libs/asker/src/asker-nats/agent.consumer.service.ts deleted file mode 100644 index 6833e8859fa74bfb4de53567cfa9582d0fcba25c..0000000000000000000000000000000000000000 --- a/libs/asker/src/asker-nats/agent.consumer.service.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { - Injectable, - Logger, - OnModuleDestroy, - OnModuleInit, -} from "@nestjs/common"; -import { AgentService } from "../asker/agent.service"; -import { ConsumerService } from "@ocm-engine/nats"; -import { ConfigService } from "@nestjs/config"; -import { IConfAgent } from "@ocm-engine/config"; -import { GatewayClient } from "@ocm-engine/clients"; -import { - AcceptCredentialOfferRequestDto, - AcceptProofRequestDto, - CONNECTION_ACCEPT, - CONNECTION_CREATE, - CONNECTION_GET, - CONNECTION_LIST, - CreateCredentialDefinitionRequsetDto, - CreateInvitationResponseDto, - CreateSchemaRequestDto, - CRED_DEF_CREATE, - CRED_ISSUE, - CRED_LIST, - CRED_OFFER_ACCEPT, - CRED_OFFER_LIST, - GetConnectionRequestDto, - GetSchemaRequestDto, - IssueCredentialRequestDto, - IssueProofRequestDto, - MakeBasicMessageRequestDto, - MESSAGE_MAKE, - PROOF_ACCEPT, - PROOF_ISSUE, - PROOF_LIST, - SCHEMA_CREATE, - SCHEMA_GET, - SCHEMA_LIST, -} from "@ocm-engine/dtos"; -import asyncRetry from "async-retry"; - -@Injectable() -export class AgentConsumerService implements OnModuleInit, OnModuleDestroy { - private readonly logger = new Logger(AgentConsumerService.name); - constructor( - private readonly agentService: AgentService, - private readonly consumerService: ConsumerService, - private readonly configService: ConfigService, - private readonly gatewayClient: GatewayClient, - ) {} - - async onModuleInit(): Promise<void> { - const config = this.configService.get<IConfAgent>("agent"); - - if (config?.agentIsRest) { - this.logger.log( - "Agent is configured as rest, there is no need for consumer!", - ); - return; - } - - await this.consumerService.subscribe(async (event) => { - this.logger.debug(JSON.stringify(event, null, 2)); - let data; - let dto; - - await asyncRetry( - async () => { - switch (event.type) { - case CONNECTION_CREATE: - data = await this.agentService.createInvitation(); - break; - case CONNECTION_ACCEPT: - dto = event.data as CreateInvitationResponseDto; - data = await this.agentService.acceptInvitation( - dto.invitationUrl, - ); - break; - - case CONNECTION_LIST: - data = await this.agentService.fetchConnections(); - break; - - case CONNECTION_GET: - dto = event.data as GetConnectionRequestDto; - data = await this.agentService.getConnectionById( - dto.connectionId, - ); - break; - - case SCHEMA_CREATE: - dto = event.data as CreateSchemaRequestDto; - data = await this.agentService.createSchema(dto); - break; - case SCHEMA_LIST: - data = await this.agentService.fetchSchemas(); - break; - - case SCHEMA_GET: - dto = event.data as GetSchemaRequestDto; - data = await this.agentService.getSchemaById(dto.schemaId); - break; - case CRED_DEF_CREATE: - data = await this.agentService.createCredentialDefinition( - event.data as CreateCredentialDefinitionRequsetDto, - ); - break; - - case CRED_ISSUE: - data = await this.agentService.issueCredential( - event.data as IssueCredentialRequestDto, - ); - break; - - case CRED_LIST: - data = await this.agentService.credentials(); - break; - - case CRED_OFFER_LIST: - data = await this.agentService.credentialByStatedOfferReceived(); - break; - - case CRED_OFFER_ACCEPT: - dto = event.data as AcceptCredentialOfferRequestDto; - data = await this.agentService.acceptCredential( - dto.credentialRecordId, - ); - break; - - case PROOF_ISSUE: - dto = event.data as IssueProofRequestDto; - data = await this.agentService.issueProof(dto); - break; - - case PROOF_LIST: - data = await this.agentService.proofs(); - break; - - case PROOF_ACCEPT: - dto = event.data as AcceptProofRequestDto; - data = await this.agentService.acceptProof(dto.proofRecordId); - break; - - case MESSAGE_MAKE: - dto = event.data as MakeBasicMessageRequestDto; - data = await this.agentService.sendMessage(dto); - break; - } - }, - { - retries: 5, - maxTimeout: 5000, - onRetry: (error) => { - this.logger.log(JSON.stringify(error, null, 2)); - this.logger.error(`Fail...${error.message}`); - }, - }, - ); - - event.data = data; - this.logger.debug(`before sending ${JSON.stringify(event, null, 2)}`); - this.gatewayClient.sendPayload(event); - - return; - }); - } - - async onModuleDestroy(): Promise<void> { - this.logger.log("disconnecting from broker"); - await this.consumerService.disconnect(); - } -} diff --git a/libs/asker/src/asker.dynamic.module.ts b/libs/asker/src/asker.dynamic.module.ts deleted file mode 100644 index 6db80f78127841bf7b41c3fcdfd79672dd070bd4..0000000000000000000000000000000000000000 --- a/libs/asker/src/asker.dynamic.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { DynamicModule, Module } from "@nestjs/common"; -import { ConfigModule } from "@nestjs/config"; -import { AskerRestModule } from "./asker-rest/asker.rest.module"; -import { AskerNatsModule } from "./asker-nats/asker.nats.module"; -import { AskerModule } from "./asker/asker.module"; -import * as process from "process"; - -@Module({}) -export class AskerDynamicModule { - static forRootAsync(): DynamicModule { - const isRest = process.env["AGENT_IS_REST"] === "true"; - - const module = isRest ? AskerRestModule : AskerNatsModule; - - return { - module: AskerDynamicModule, - imports: [ConfigModule, AskerModule, module], - providers: [module], - }; - } -} diff --git a/libs/asker/src/index.ts b/libs/asker/src/index.ts deleted file mode 100644 index a6cf6c3829fdbf75995e2dd83b3717f1225ed5c6..0000000000000000000000000000000000000000 --- a/libs/asker/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./asker/asker.module"; -export * from "./asker/agent.service"; -export * from "./asker/asker.service"; -export * from "./asker.dynamic.module"; -export * from "./asker-rest/asker.rest.module"; diff --git a/libs/clients/src/lib/attestation.manager.client.ts b/libs/clients/src/lib/attestation.manager.client.ts index 4b66e730d589a90217df024762b7302ae285988b..0b462f0e231c4fed042b1d3bafdd407ca06aa579 100644 --- a/libs/clients/src/lib/attestation.manager.client.ts +++ b/libs/clients/src/lib/attestation.manager.client.ts @@ -56,11 +56,7 @@ export class AttestationManagerClient { ); return lastValueFrom(this.client.send(pattern, payload)).catch((e) => { - if (e.message === "Internal server error") { - throw new InternalServerErrorException(); - } - - throw new BadRequestException(e.message); + throw new InternalServerErrorException(e.message); }); } } diff --git a/libs/clients/src/lib/connection.manager.client.ts b/libs/clients/src/lib/connection.manager.client.ts index 3554fb1e95286ef0ab00a8f576af095d05d331c3..4336c16ecaf9c9f8d49fe989958d8b90ada24c72 100644 --- a/libs/clients/src/lib/connection.manager.client.ts +++ b/libs/clients/src/lib/connection.manager.client.ts @@ -53,11 +53,7 @@ export class ConnectionManagerClient { ); return lastValueFrom(this.client.send(pattern, payload)).catch((e) => { - if (e.message === "Internal server error") { - throw new InternalServerErrorException(); - } - - throw new BadRequestException(e.message); + throw new InternalServerErrorException(e.message); }); } } diff --git a/libs/clients/src/lib/proof.manager.client.ts b/libs/clients/src/lib/proof.manager.client.ts index 3619eca4d3af21187959dd01742cc3de4786f8df..37930bb1ec5771e14f53713665d8253b7b4b9fb9 100644 --- a/libs/clients/src/lib/proof.manager.client.ts +++ b/libs/clients/src/lib/proof.manager.client.ts @@ -52,11 +52,7 @@ export class ProofManagerClient { ); return lastValueFrom(this.client.send(pattern, payload)).catch((e) => { - if (e.message === "Internal server error") { - throw new InternalServerErrorException(); - } - - throw new BadRequestException(e.message); + throw new InternalServerErrorException(e.message); }); } } diff --git a/libs/dtos/src/dtos/requests/get.connection.request.dto.ts b/libs/dtos/src/dtos/requests/get.connection.request.dto.ts index 7c1b528f2ae52296e7ca002422160b5ca6d54399..786adaf646d3a1d7e3ec06060b4fa478fa3f47d4 100644 --- a/libs/dtos/src/dtos/requests/get.connection.request.dto.ts +++ b/libs/dtos/src/dtos/requests/get.connection.request.dto.ts @@ -1,6 +1,7 @@ import { IsNotEmpty, IsString } from "class-validator"; export class GetConnectionRequestDto { + //@example 6464b521-005a-4379-91e0-a3692b31cafd @IsNotEmpty() @IsString() connectionId: string; diff --git a/libs/dtos/src/dtos/requests/issue.credential.request.dto.ts b/libs/dtos/src/dtos/requests/issue.credential.request.dto.ts index fb382c154bd2e75a1cedbcabfa25d99519aadc96..26684dabca4657623c67bfe6534ae61511dfd4a3 100644 --- a/libs/dtos/src/dtos/requests/issue.credential.request.dto.ts +++ b/libs/dtos/src/dtos/requests/issue.credential.request.dto.ts @@ -16,11 +16,14 @@ export class IssueCredentialAttributes { } export class IssueCredentialRequestDto { + //@example 6464b521-005a-4379-91e0-a3692b31cafd @IsString() @IsNotEmpty() connectionId: string; + //@example did:indy:LEDGER:5Pf67NsEtnU42GJGETT6Xe/anoncreds/v0/CLAIM_DEF/855916/test mest cred def @IsString() + @IsNotEmpty() credentialDefinitionId: string; @IsArray() diff --git a/libs/dtos/src/dtos/requests/issue.proof.request.dto.ts b/libs/dtos/src/dtos/requests/issue.proof.request.dto.ts index c9469f41322eb58cd5bde145e72f21b883526f89..7e9ac7e167043c3264f1f39ca8acc208ecacd566 100644 --- a/libs/dtos/src/dtos/requests/issue.proof.request.dto.ts +++ b/libs/dtos/src/dtos/requests/issue.proof.request.dto.ts @@ -23,6 +23,7 @@ export class IssueProofAttribute { } export class IssueProofRequestDto { + //@example 6464b521-005a-4379-91e0-a3692b31cafd @IsString() @IsNotEmpty() @IsOptional() diff --git a/libs/dtos/src/dtos/requests/make.basic.message.request.dto.ts b/libs/dtos/src/dtos/requests/make.basic.message.request.dto.ts index 33f2130e4bc0f95692f6a04a6caa5b59ade6cdda..a5ab200eb1ceaf52810096ecdc3220df2d93eac0 100644 --- a/libs/dtos/src/dtos/requests/make.basic.message.request.dto.ts +++ b/libs/dtos/src/dtos/requests/make.basic.message.request.dto.ts @@ -1,10 +1,12 @@ import { IsNotEmpty, IsString } from "class-validator"; export class MakeBasicMessageRequestDto { + // @example 6464b521-005a-4379-91e0-a3692b31cafd @IsNotEmpty() @IsString() connectionId: string; + // @example "hello world" @IsNotEmpty() @IsString() message: string; diff --git a/libs/dtos/src/dtos/responses/accept.invitation.response.dto.ts b/libs/dtos/src/dtos/responses/accept.invitation.response.dto.ts index bb8dd57c26824fbda6582224dc3ea6a3aadbfffb..c3e482ae58fed1ae2d5448b67003fce64406cf38 100644 --- a/libs/dtos/src/dtos/responses/accept.invitation.response.dto.ts +++ b/libs/dtos/src/dtos/responses/accept.invitation.response.dto.ts @@ -1,5 +1,6 @@ export class AcceptInvitationResponseDto { - public id: string; + public connectionId: string; + public connectionName?: string; public did?: string; public invitationDid?: string; public outOfBandId?: string; diff --git a/libs/dtos/src/dtos/responses/issue.proof.response.dto.ts b/libs/dtos/src/dtos/responses/issue.proof.response.dto.ts index 06cd5546ca6c5d7268d8225b7be67ccbe4fdd649..01d9789d07ab383f724c0f25b21037d387043419 100644 --- a/libs/dtos/src/dtos/responses/issue.proof.response.dto.ts +++ b/libs/dtos/src/dtos/responses/issue.proof.response.dto.ts @@ -1,18 +1,11 @@ -import { - ArrayMinSize, - IsArray, - IsDateString, - IsNotEmpty, - IsString, - ValidateNested, -} from "class-validator"; -import { Type } from "class-transformer"; +import { IsDateString, IsNotEmpty, IsString } from "class-validator"; export class IssueProofResponseDto { @IsString() @IsNotEmpty() proofId: string; + //@example 6464b521-005a-4379-91e0-a3692b31cafd @IsString() connectionId?: string; diff --git a/libs/dtos/src/dtos/responses/make.basic.message.response.dto.ts b/libs/dtos/src/dtos/responses/make.basic.message.response.dto.ts index 684b4d311ace58a10ccedd9c0f7f4fd642eb76a4..b1680199759aa47376774bc2e24fbc2c32ba6366 100644 --- a/libs/dtos/src/dtos/responses/make.basic.message.response.dto.ts +++ b/libs/dtos/src/dtos/responses/make.basic.message.response.dto.ts @@ -5,6 +5,22 @@ export class MakeBasicMessageResponseDto { @IsString() id: string; + // @example 6464b521-005a-4379-91e0-a3692b31cafd + @IsNotEmpty() + @IsString() + connectionId: string; + + // @example "example-ocm-name" + @IsNotEmpty() + @IsString() + from?: string; + + // @example "example-ocm-name" + @IsNotEmpty() + @IsString() + to?: string; + + // @example "hello world" @IsNotEmpty() @IsString() message: string; diff --git a/libs/dtos/src/events/dtoToEventTransformer.ts b/libs/dtos/src/events/dtoToEventTransformer.ts index e0c2c3046824e89f9a7be5f29488aa6df45c56b0..cde079ed94ef10f8e5f83a9badd32af348e51030 100644 --- a/libs/dtos/src/events/dtoToEventTransformer.ts +++ b/libs/dtos/src/events/dtoToEventTransformer.ts @@ -39,7 +39,7 @@ export const makeEvent = (payload: { | BasicMessageEvent; source: string; }) => { - if (ALL_EVENTS.includes(payload.type)) { + if (!ALL_EVENTS.includes(payload.type)) { throw new ConnectionUnsupportedTypeError(); } diff --git a/libs/ledgers/src/didgram-test/didgram-test.provider.ts b/libs/ledgers/src/didgram-test/didgram-test.provider.ts new file mode 100644 index 0000000000000000000000000000000000000000..39da899bfe194d850c17aa7971c294ce89719afa --- /dev/null +++ b/libs/ledgers/src/didgram-test/didgram-test.provider.ts @@ -0,0 +1,54 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { IRegistrator } from "../IRegistrator"; +import genesisFile from "./genesis-file"; +import axios, { AxiosError } from "axios"; +import { IndyVdrPoolConfig } from "@aries-framework/indy-vdr"; +import { LedgerProviderFailRegistrationError } from "@ocm-engine/dtos"; + +const NAME = "DIDGRAM_TEST"; +const URL = "http://ledger.didgram.pro/register"; + +@Injectable() +export class DidgramTestProvider implements IRegistrator { + private readonly logger: Logger = new Logger(DidgramTestProvider.name); + + getName = (): string => { + return NAME; + }; + + register = async ( + unqualifiedIndyDid: string, + verkey: string, + ): Promise<string> => { + const did = `did:indy:didgram:test:${unqualifiedIndyDid}`; + + this.logger.log(`Trying to register ${did} to didram test`); + try { + await axios.post(URL, { + did: unqualifiedIndyDid, + verkey, + role: "ENDORSER", + }); + + this.logger.log("Registration successful"); + return did; + } catch (e) { + this.logger.log("Registration failed"); + this.logger.log("DIDGRAM Registration failed"); + + if (e instanceof Error || e instanceof AxiosError) { + throw new LedgerProviderFailRegistrationError(e.message); + } + throw new Error("DIDGRAM registration fail - Reason UNKNOWN"); + } + }; + + getNetworkConf = (): IndyVdrPoolConfig => { + return { + genesisTransactions: genesisFile, + indyNamespace: "didgram:test", + isProduction: false, + connectOnStartup: true, + }; + }; +} diff --git a/libs/ledgers/src/didgram-test/genesis-file.ts b/libs/ledgers/src/didgram-test/genesis-file.ts new file mode 100644 index 0000000000000000000000000000000000000000..4a2891cf5679a5ea8327f0fbdd8f53dfdebb3d17 --- /dev/null +++ b/libs/ledgers/src/didgram-test/genesis-file.ts @@ -0,0 +1,5 @@ +export default `{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node1","blskey":"4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba","blskey_pop":"RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1","client_ip":"78.46.191.128","client_port":9702,"node_ip":"78.46.191.128","node_port":9701,"services":["VALIDATOR"]},"dest":"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv"},"metadata":{"from":"Th7MpTaRZVRYnPiabds81Y"},"type":"0"},"txnMetadata":{"seqNo":1,"txnId":"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62"},"ver":"1"} +{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node2","blskey":"37rAPpXVoxzKhz7d9gkUe52XuXryuLXoM6P6LbWDB7LSbG62Lsb33sfG7zqS8TK1MXwuCHj1FKNzVpsnafmqLG1vXN88rt38mNFs9TENzm4QHdBzsvCuoBnPH7rpYYDo9DZNJePaDvRvqJKByCabubJz3XXKbEeshzpz4Ma5QYpJqjk","blskey_pop":"Qr658mWZ2YC8JXGXwMDQTzuZCWF7NK9EwxphGmcBvCh6ybUuLxbG65nsX4JvD4SPNtkJ2w9ug1yLTj6fgmuDg41TgECXjLCij3RMsV8CwewBVgVN67wsA45DFWvqvLtu4rjNnE9JbdFTc1Z4WCPA3Xan44K1HoHAq9EVeaRYs8zoF5","client_ip":"78.46.191.128","client_port":9704,"node_ip":"78.46.191.128","node_port":9703,"services":["VALIDATOR"]},"dest":"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb"},"metadata":{"from":"EbP4aYNeTHL6q385GuVpRV"},"type":"0"},"txnMetadata":{"seqNo":2,"txnId":"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc"},"ver":"1"} +{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node3","blskey":"3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5","blskey_pop":"QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh","client_ip":"78.46.191.128","client_port":9706,"node_ip":"78.46.191.128","node_port":9705,"services":["VALIDATOR"]},"dest":"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya"},"metadata":{"from":"4cU41vWW82ArfxJxHkzXPG"},"type":"0"},"txnMetadata":{"seqNo":3,"txnId":"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4"},"ver":"1"} +{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node4","blskey":"2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw","blskey_pop":"RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP","client_ip":"78.46.191.128","client_port":9708,"node_ip":"78.46.191.128","node_port":9707,"services":["VALIDATOR"]},"dest":"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA"},"metadata":{"from":"TWwCRQRZ2ZHMJFn9TzLp7W"},"type":"0"},"txnMetadata":{"seqNo":4,"txnId":"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008"},"ver":"1"} +`; diff --git a/libs/ledgers/src/ledgers.module.ts b/libs/ledgers/src/ledgers.module.ts index eac97105983bea723cf420713496f267c408b45b..cbc2ca3610896ed045165312a907e57619383f2b 100644 --- a/libs/ledgers/src/ledgers.module.ts +++ b/libs/ledgers/src/ledgers.module.ts @@ -3,11 +3,17 @@ import { LedgersService } from "./ledgers.service"; import { IdunionProvider } from "./idunion/idunion.provider"; import { BcovrinTestProvider } from "./bcovrin-test/bcovrin-test.provider"; import { ConfigModule } from "@nestjs/config"; +import { DidgramTestProvider } from "./didgram-test/didgram-test.provider"; @Module({ imports: [ConfigModule], controllers: [], - providers: [LedgersService, IdunionProvider, BcovrinTestProvider], + providers: [ + LedgersService, + IdunionProvider, + BcovrinTestProvider, + DidgramTestProvider, + ], exports: [LedgersService], }) export class LedgersModule {} diff --git a/libs/ledgers/src/ledgers.service.ts b/libs/ledgers/src/ledgers.service.ts index 8debe072e9612412522d2bd02d67c8bfaaa80f9b..c843a87efba5563bfeb46a6158158a26551ff2fc 100644 --- a/libs/ledgers/src/ledgers.service.ts +++ b/libs/ledgers/src/ledgers.service.ts @@ -5,6 +5,7 @@ import { IRegistrator } from "./IRegistrator"; import { IndyVdrPoolConfig } from "@aries-framework/indy-vdr"; import { ConfigService } from "@nestjs/config"; import { ILedgers } from "@ocm-engine/config"; +import { DidgramTestProvider } from "./didgram-test/didgram-test.provider"; @Injectable() export class LedgersService { @@ -15,9 +16,10 @@ export class LedgersService { constructor( private bcovrin: BcovrinTestProvider, private idUnion: IdunionProvider, + private didGram: DidgramTestProvider, private configService: ConfigService, ) { - this.providers = [bcovrin, idUnion]; + this.providers = [bcovrin, idUnion, didGram]; //FIXME: properly check for null // eslint-disable-next-line @typescript-eslint/no-non-null-assertion diff --git a/libs/nats/src/consumer.nats.service.ts b/libs/nats/src/consumer.nats.service.ts index 8f1545c3c574a5ec2bdcf0386ea657a6a179f06b..88157ea13db32fc6687e64595d2b903f688160c2 100644 --- a/libs/nats/src/consumer.nats.service.ts +++ b/libs/nats/src/consumer.nats.service.ts @@ -26,6 +26,7 @@ export class ConsumerService extends NatsBaseService { private registerConsumer = (stream: string) => { const consumerConfig: ConsumerConfig = { + max_deliver: 3, name: this.agentConfig.agentConsumerName, ack_policy: AckPolicy.Explicit, deliver_policy: DeliverPolicy.All, @@ -85,6 +86,7 @@ export class ConsumerService extends NatsBaseService { `Could not handle consuming event with reason, ${e.message}`, ); } + //TODO: we should implement dead letter queue return message.nak(); }) .finally(() => rl.unlock()); diff --git a/package.json b/package.json index ef466b42ebfe6d96a905c989fe66974dc77822eb..a21ab6a5b8765c51e5699e46c7f81d025d6e538e 100644 --- a/package.json +++ b/package.json @@ -3,28 +3,30 @@ "version": "0.0.0", "license": "Apache-2.0", "scripts": { - "build:all": "yarn build:agent && yarn build:cm && yarn build:am && yarn build:pm && yarn build:gateway", - "build:agent": "nx run agent:build:development", + "build:all": "yarn build:agent && yarn build:cm && yarn build:am && yarn build:pm && yarn build:gw", + "build:agent": "nx run agent:build:development --parallel=3", "build:agent:production": "nx run agent:build:production", - "build:cm": "nx run connection-manager:build:development", + "build:cm": "nx run connection-manager:build:development --parallel=3", "build:cm:production": "nx run connection-manager:build:production", - "build:am": "nx run attestation-manager:build:development", + "build:am": "nx run attestation-manager:build:development --parallel=3", "build:am:production": "nx run attestation-manager:build:production", - "build:pm": "nx run proof-manager:build:development", + "build:pm": "nx run proof-manager:build:development --parallel=3", "build:pm:production": "nx run proof-manager:build:production", - "build:gateway": "nx run gateway:build:development", - "build:gateway:production": "nx run gateway:build:production", + "build:gw": "nx run gateway:build:development --parallel=3", + "build:gw:production": "nx run gateway:build:production", - "serve:all": "concurrently \"yarn serve:agent\" \"yarn serve:cm\" \"yarn serve:am\" \"yarn serve:pm\" \"yarn serve:gateway\"", + "serve:all": "concurrently \"yarn serve:agent\" \"yarn serve:cm\" \"yarn serve:am\" \"yarn serve:pm\" \"yarn serve:gw\"", "serve:agent": "nx run agent:serve:development", "serve:cm": "nx run connection-manager:serve:development", "serve:am": "nx run attestation-manager:serve:development", "serve:pm": "nx run proof-manager:serve:development", - "serve:gateway": "nx run gateway:serve:development", + "serve:gw": "nx run gateway:serve:development", - "infra": "cd compose && docker-compose --profile issuer --profile holder up -d", - "infra:issuer": "cd compose && docker-compose --profile issuer up -d", - "infra:holder": "cd compose && docker-compose --profile holder up -d", + "infra": "cd compose && docker-compose --profile issuer --profile holder up -d --build", + "infra:down": "cd compose && docker-compose --profile issuer --profile holder down", + "infra:status" : "cd compose && docker-compose ps -a", + "infra:issuer": "cd compose && docker-compose --profile issuer up -d --build", + "infra:holder": "cd compose && docker-compose --profile holder up -d --build", "infra:issuer:stop": "cd compose && docker-compose --profile issuer stop", "infra:holder:stop": "cd compose && docker-compose --profile holder stop", "infra:local": "cd compose && docker-compose -f=docker-compose.infra.yml up -d", diff --git a/tsconfig.base.json b/tsconfig.base.json index 335749b1ca62759f966401bf464219890e3935cd..17ada64742a2f2037eceeab3dd741487ab7474c1 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -19,7 +19,7 @@ "strictPropertyInitialization": false, "baseUrl": ".", "paths": { - "@ocm-engine/asker": ["libs/asker/src/index.ts"], + "@ocm-engine/askar": ["libs/askar/src/index.ts"], "@ocm-engine/clients": ["libs/clients/src/index.ts"], "@ocm-engine/config": ["libs/config/src/index.ts"], "@ocm-engine/dtos": ["libs/dtos/src/index.ts"],