From e8fedd76fde15e27d26cdeab863f25601c57da3b Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 5 Mar 2026 15:01:31 +0530 Subject: [PATCH 1/6] fix: add polygon resolver and registrar Signed-off-by: Krishna Waske --- package.json | 2 +- src/cliAgent.ts | 27 ++-- src/routes/routes.ts | 224 +++++++++++++++++++++++++-- src/routes/swagger.json | 327 ++++++++++++++++++++++++++++++++++++++-- yarn.lock | 8 +- 5 files changed, 539 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 8b2c0718..d9b408af 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "validate": "yarn lint && yarn check-types && yarn check-format" }, "dependencies": { - "@ayanworks/credo-polygon-w3c-module": "2.0.0", + "@ayanworks/credo-polygon-w3c-module": "^2.0.0", "@credo-ts/anoncreds": "0.6.2", "@credo-ts/askar": "0.6.2", "@credo-ts/core": "0.6.2", diff --git a/src/cliAgent.ts b/src/cliAgent.ts index 54d93054..33d91d51 100644 --- a/src/cliAgent.ts +++ b/src/cliAgent.ts @@ -65,6 +65,7 @@ import { setupServer } from './server' import { generateSecretKey } from './utils/helpers' import { TsLogger } from './utils/logger' import { getMixedCredentialRequestToCredentialMapper, getTrustedCerts } from './utils/oid4vc-agent' +import { PolygonDidRegistrar, PolygonDidResolver, PolygonModule } from '@ayanworks/credo-polygon-w3c-module' export type Transports = 'ws' | 'http' export type InboundTransport = { @@ -174,15 +175,14 @@ const getModules = ( new IndyVdrIndyDidRegistrar(), new KeyDidRegistrar(), new JwkDidRegistrar(), - // TODO: We can enable polygon later - // , new PolygonDidRegistrar() + new PolygonDidRegistrar() ], resolvers: [ new IndyVdrIndyDidResolver(), new KeyDidResolver(), new WebDidResolver(), new JwkDidResolver(), - // , new PolygonDidResolver() + new PolygonDidResolver() ], }), @@ -237,17 +237,16 @@ const getModules = ( }), questionAnswer: new QuestionAnswerModule(), - // Todo: We can remove this polygon module for time being - // polygon: new PolygonModule({ - // didContractAddress: didRegistryContractAddress - // ? didRegistryContractAddress - // : (process.env.DID_CONTRACT_ADDRESS as string), - // schemaManagerContractAddress: - // schemaManagerContractAddress || (process.env.SCHEMA_MANAGER_CONTRACT_ADDRESS as string), - // fileServerToken: fileServerToken ? fileServerToken : (process.env.FILE_SERVER_TOKEN as string), - // rpcUrl: rpcUrl ? rpcUrl : (process.env.RPC_URL as string), - // serverUrl: fileServerUrl ? fileServerUrl : (process.env.SERVER_URL as string), - // }), + polygon: new PolygonModule({ + didContractAddress: didRegistryContractAddress + ? didRegistryContractAddress + : (process.env.DID_CONTRACT_ADDRESS as string), + schemaManagerContractAddress: + schemaManagerContractAddress || (process.env.SCHEMA_MANAGER_CONTRACT_ADDRESS as string), + fileServerToken: fileServerToken ? fileServerToken : (process.env.FILE_SERVER_TOKEN as string), + rpcUrl: rpcUrl ? rpcUrl : (process.env.RPC_URL as string), + serverUrl: fileServerUrl ? fileServerUrl : (process.env.SERVER_URL as string), + }), openid4vc: new OpenId4VcModule({ app: expressApp, issuer: { diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 496f0dbe..55f296e3 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -6,6 +6,8 @@ import { fetchMiddlewares, ExpressTemplateService } from '@tsoa/runtime'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { X509Controller } from './../controllers/x509/x509.Controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa +import { Polygon } from './../controllers/polygon/PolygonController'; +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { VerificationSessionsController } from './../controllers/openid4vc/verifier-sessions/verification-sessions.Controller'; // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa import { IssuerController } from './../controllers/openid4vc/issuers/issuer.Controller'; @@ -222,6 +224,66 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "Record_string.unknown_": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidOperation.Create": { + "dataType": "refEnum", + "enums": ["createDID"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CreateDidOperationOptions": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"serviceEndpoint":{"dataType":"string"},"operation":{"ref":"DidOperation.Create","required":true}},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidOperation.Update": { + "dataType": "refEnum", + "enums": ["updateDIDDoc"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "Record_string.any_": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidDocument": { + "dataType": "refAlias", + "type": {"ref":"Record_string.any_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "UpdateDidOperationOptions": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"did":{"dataType":"string","required":true},"didDocument":{"ref":"DidDocument","required":true},"operation":{"ref":"DidOperation.Update","required":true}},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidOperation.Deactivate": { + "dataType": "refEnum", + "enums": ["deactivate"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DeactivateDidOperationOptions": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"did":{"dataType":"string","required":true},"operation":{"ref":"DidOperation.Deactivate","required":true}},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidOperation.AddResource": { + "dataType": "refEnum", + "enums": ["addResource"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AddResourceDidOperationOptions": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"did":{"dataType":"string","required":true},"resource":{"dataType":"object","required":true},"resourceId":{"dataType":"string","required":true},"operation":{"ref":"DidOperation.AddResource","required":true}},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidOperationOptions": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"ref":"CreateDidOperationOptions"},{"ref":"UpdateDidOperationOptions"},{"ref":"DeactivateDidOperationOptions"},{"ref":"AddResourceDidOperationOptions"}],"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "JwtObject": { "dataType": "refObject", "properties": { @@ -546,11 +608,6 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Record_string.unknown_": { - "dataType": "refAlias", - "type": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"},"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "OpenId4VcVerificationSessionRecord": { "dataType": "refAlias", "type": {"ref":"Record_string.unknown_","validators":{}}, @@ -974,11 +1031,6 @@ const models: TsoaRoute.Models = { "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"label":{"dataType":"string","required":true}},"validators":{}}, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "Record_string.any_": { - "dataType": "refAlias", - "type": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"},"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "MetadataValue": { "dataType": "refAlias", "type": {"ref":"Record_string.any_","validators":{}}, @@ -1304,11 +1356,6 @@ const models: TsoaRoute.Models = { "enums": ["a128gcm","a256gcm","a128cbchs256","a256cbchs512","a128kw","a256kw","bls12381g1","bls12381g2","c20p","xc20p","ed25519","x25519","k256","p256","p384"], }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "DidDocument": { - "dataType": "refAlias", - "type": {"ref":"Record_string.any_","validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "DidCreate": { "dataType": "refObject", "properties": { @@ -1725,6 +1772,153 @@ export function RegisterRoutes(app: Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsPolygon_createKeyPair: Record = { + }; + app.post('/polygon/create-keys', + authenticateMiddleware([{"jwt":["tenant","dedicated","Basewallet"]}]), + ...(fetchMiddlewares(Polygon)), + ...(fetchMiddlewares(Polygon.prototype.createKeyPair)), + + async function Polygon_createKeyPair(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsPolygon_createKeyPair, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(Polygon); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'createKeyPair', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsPolygon_createSchema: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + createSchemaRequest: {"in":"body","name":"createSchemaRequest","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"schema":{"ref":"Record_string.unknown_","required":true},"schemaName":{"dataType":"string","required":true},"did":{"dataType":"string","required":true}}}, + }; + app.post('/polygon/create-schema', + authenticateMiddleware([{"jwt":["tenant","dedicated"]}]), + ...(fetchMiddlewares(Polygon)), + ...(fetchMiddlewares(Polygon.prototype.createSchema)), + + async function Polygon_createSchema(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsPolygon_createSchema, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(Polygon); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'createSchema', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsPolygon_estimateTransaction: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + estimateTransactionRequest: {"in":"body","name":"estimateTransactionRequest","required":true,"ref":"DidOperationOptions"}, + }; + app.post('/polygon/estimate-transaction', + authenticateMiddleware([{"jwt":["tenant","dedicated","Basewallet"]}]), + ...(fetchMiddlewares(Polygon)), + ...(fetchMiddlewares(Polygon.prototype.estimateTransaction)), + + async function Polygon_estimateTransaction(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsPolygon_estimateTransaction, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(Polygon); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'estimateTransaction', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + const argsPolygon_getSchemaById: Record = { + request: {"in":"request","name":"request","required":true,"dataType":"object"}, + did: {"in":"path","name":"did","required":true,"dataType":"string"}, + schemaId: {"in":"path","name":"schemaId","required":true,"dataType":"string"}, + }; + app.get('/polygon/:did/:schemaId', + authenticateMiddleware([{"jwt":["tenant","dedicated"]}]), + ...(fetchMiddlewares(Polygon)), + ...(fetchMiddlewares(Polygon.prototype.getSchemaById)), + + async function Polygon_getSchemaById(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: argsPolygon_getSchemaById, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(Polygon); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'getSchemaById', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa const argsVerificationSessionsController_createProofRequest: Record = { request: {"in":"request","name":"request","required":true,"dataType":"object"}, createAuthorizationRequest: {"in":"body","name":"createAuthorizationRequest","required":true,"ref":"CreateAuthorizationRequest"}, diff --git a/src/routes/swagger.json b/src/routes/swagger.json index 0995acc3..55f04345 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -390,6 +390,133 @@ "type": "object", "additionalProperties": false }, + "Record_string.unknown_": { + "properties": {}, + "additionalProperties": {}, + "type": "object", + "description": "Construct a type with a set of properties K of type T" + }, + "DidOperation.Create": { + "enum": [ + "createDID" + ], + "type": "string" + }, + "CreateDidOperationOptions": { + "properties": { + "serviceEndpoint": { + "type": "string" + }, + "operation": { + "$ref": "#/components/schemas/DidOperation.Create" + } + }, + "required": [ + "operation" + ], + "type": "object" + }, + "DidOperation.Update": { + "enum": [ + "updateDIDDoc" + ], + "type": "string" + }, + "Record_string.any_": { + "properties": {}, + "additionalProperties": {}, + "type": "object", + "description": "Construct a type with a set of properties K of type T" + }, + "DidDocument": { + "$ref": "#/components/schemas/Record_string.any_" + }, + "UpdateDidOperationOptions": { + "properties": { + "did": { + "type": "string" + }, + "didDocument": { + "$ref": "#/components/schemas/DidDocument" + }, + "operation": { + "$ref": "#/components/schemas/DidOperation.Update" + } + }, + "required": [ + "did", + "didDocument", + "operation" + ], + "type": "object" + }, + "DidOperation.Deactivate": { + "enum": [ + "deactivate" + ], + "type": "string" + }, + "DeactivateDidOperationOptions": { + "properties": { + "did": { + "type": "string" + }, + "operation": { + "$ref": "#/components/schemas/DidOperation.Deactivate" + } + }, + "required": [ + "did", + "operation" + ], + "type": "object" + }, + "DidOperation.AddResource": { + "enum": [ + "addResource" + ], + "type": "string" + }, + "AddResourceDidOperationOptions": { + "properties": { + "did": { + "type": "string" + }, + "resource": { + "additionalProperties": false, + "type": "object" + }, + "resourceId": { + "type": "string" + }, + "operation": { + "$ref": "#/components/schemas/DidOperation.AddResource" + } + }, + "required": [ + "did", + "resource", + "resourceId", + "operation" + ], + "type": "object" + }, + "DidOperationOptions": { + "anyOf": [ + { + "$ref": "#/components/schemas/CreateDidOperationOptions" + }, + { + "$ref": "#/components/schemas/UpdateDidOperationOptions" + }, + { + "$ref": "#/components/schemas/DeactivateDidOperationOptions" + }, + { + "$ref": "#/components/schemas/AddResourceDidOperationOptions" + } + ] + }, "JwtObject": { "properties": { "alg": { @@ -1149,12 +1276,6 @@ "type": "object", "additionalProperties": false }, - "Record_string.unknown_": { - "properties": {}, - "additionalProperties": {}, - "type": "object", - "description": "Construct a type with a set of properties K of type T" - }, "OpenId4VcVerificationSessionRecord": { "$ref": "#/components/schemas/Record_string.unknown_" }, @@ -2193,12 +2314,6 @@ ], "type": "object" }, - "Record_string.any_": { - "properties": {}, - "additionalProperties": {}, - "type": "object", - "description": "Construct a type with a set of properties K of type T" - }, "MetadataValue": { "$ref": "#/components/schemas/Record_string.any_" }, @@ -2934,9 +3049,6 @@ ], "type": "string" }, - "DidDocument": { - "$ref": "#/components/schemas/Record_string.any_" - }, "DidCreate": { "properties": { "keyType": { @@ -3641,6 +3753,191 @@ } } }, + "/polygon/create-keys": { + "post": { + "operationId": "CreateKeyPair", + "responses": { + "200": { + "description": "Secp256k1KeyPair", + "content": { + "application/json": { + "schema": { + "properties": { + "address": { + "type": "string" + }, + "publicKeyBase58": { + "type": "string" + }, + "privateKey": { + "type": "string" + } + }, + "required": [ + "address", + "publicKeyBase58", + "privateKey" + ], + "type": "object" + } + } + } + } + }, + "description": "Create Secp256k1 key pair for polygon DID", + "tags": [ + "Polygon" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated", + "Basewallet" + ] + } + ], + "parameters": [] + } + }, + "/polygon/create-schema": { + "post": { + "operationId": "CreateSchema", + "responses": { + "200": { + "description": "Schema JSON", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "description": "Create polygon based W3C schema", + "tags": [ + "Polygon" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated" + ] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "schema": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "schemaName": { + "type": "string" + }, + "did": { + "type": "string" + } + }, + "required": [ + "schema", + "schemaName", + "did" + ], + "type": "object" + } + } + } + } + } + }, + "/polygon/estimate-transaction": { + "post": { + "operationId": "EstimateTransaction", + "responses": { + "200": { + "description": "Transaction Object", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "description": "Estimate transaction", + "tags": [ + "Polygon" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated", + "Basewallet" + ] + } + ], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DidOperationOptions" + } + } + } + } + } + }, + "/polygon/{did}/{schemaId}": { + "get": { + "operationId": "GetSchemaById", + "responses": { + "200": { + "description": "Schema Object", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "description": "Fetch schema details", + "tags": [ + "Polygon" + ], + "security": [ + { + "jwt": [ + "tenant", + "dedicated" + ] + } + ], + "parameters": [ + { + "in": "path", + "name": "did", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "schemaId", + "required": true, + "schema": { + "type": "string" + } + } + ] + } + }, "/openid4vc/verification-sessions/create-presentation-request": { "post": { "operationId": "CreateProofRequest", diff --git a/yarn.lock b/yarn.lock index 3d31b382..5f9ec287 100644 --- a/yarn.lock +++ b/yarn.lock @@ -61,10 +61,10 @@ dependencies: static-eval "2.0.2" -"@ayanworks/credo-polygon-w3c-module@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@ayanworks/credo-polygon-w3c-module/-/credo-polygon-w3c-module-2.0.0.tgz#8682b3dfeffe166c7da718afac9739db825ef626" - integrity sha512-6ZJH/TtieyIQ1mxOj00JyixZ56wi2G7nhDgZEWYkQiEcY1x3IRNR75iRLTOK23NTn2tLneC6Kl5niWEg7BsCjg== +"@ayanworks/credo-polygon-w3c-module@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@ayanworks/credo-polygon-w3c-module/-/credo-polygon-w3c-module-2.0.1.tgz#dcdfb0489624cf5a994f907801a17ae98e632682" + integrity sha512-jNQYoG+eNxkJB29OuTNAJoSgekFFDqWErXX78XrGpKPrHu5SdrRTV49oDp4xFvSDk2kJyUQaEffkRfedlLgD9g== dependencies: "@ayanworks/polygon-did-registrar" "2.2.0" "@ayanworks/polygon-did-resolver" "1.0.2" From 0f240f5086cd251975cdbd59869650db56c10469 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 5 Mar 2026 17:45:57 +0530 Subject: [PATCH 2/6] fix: restore polygon module Signed-off-by: Krishna Waske --- src/utils/agent.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/utils/agent.ts b/src/utils/agent.ts index 44ea46c4..46944c93 100644 --- a/src/utils/agent.ts +++ b/src/utils/agent.ts @@ -30,6 +30,7 @@ import { indyVdr } from '@hyperledger/indy-vdr-nodejs' import { askar } from '@openwallet-foundation/askar-nodejs' import { TsLogger } from './logger' +import { PolygonModule } from '@ayanworks/credo-polygon-w3c-module' export const setupAgent = async ({ endpoints, @@ -126,13 +127,13 @@ export const setupAgent = async ({ ], }, }), - // polygon: new PolygonModule({ - // didContractAddress: '', - // schemaManagerContractAddress: '', - // fileServerToken: '', - // rpcUrl: '', - // serverUrl: '', - // }), + polygon: new PolygonModule({ + didContractAddress: '', + schemaManagerContractAddress: '', + fileServerToken: '', + rpcUrl: '', + serverUrl: '', + }), }, dependencies: agentDependencies, }) From cce1d8db3e233a8a571856f73a449fb04c47dce4 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 5 Mar 2026 18:53:52 +0530 Subject: [PATCH 3/6] fix: linting Signed-off-by: Krishna Waske --- src/cliAgent.ts | 9 +- src/controllers/auth/AuthController.ts | 2 +- .../connections/ConnectionController.ts | 3 +- .../didcomm/outofband/OutOfBandController.ts | 34 ++-- .../openid4vc/examples/issuer.examples.ts | 171 +++++++++--------- src/errorHandlingService.ts | 7 +- src/events/BasicMessageEvents.ts | 41 +++-- src/events/ConnectionEvents.ts | 39 ++-- src/events/CredentialEvents.ts | 69 +++---- src/events/ProofEvents.ts | 2 +- src/events/WebSocketEvents.ts | 2 +- src/events/openId4VcIssuanceSessionEvents.ts | 35 ++-- .../openId4VcVerificationSessionEvents.ts | 35 ++-- src/types/request.d.ts | 2 - src/utils/helpers.ts | 31 +++- src/utils/oid4vc-agent.ts | 4 +- 16 files changed, 258 insertions(+), 228 deletions(-) diff --git a/src/cliAgent.ts b/src/cliAgent.ts index 33d91d51..2b044cb7 100644 --- a/src/cliAgent.ts +++ b/src/cliAgent.ts @@ -175,14 +175,14 @@ const getModules = ( new IndyVdrIndyDidRegistrar(), new KeyDidRegistrar(), new JwkDidRegistrar(), - new PolygonDidRegistrar() + new PolygonDidRegistrar(), ], resolvers: [ new IndyVdrIndyDidResolver(), new KeyDidResolver(), new WebDidResolver(), new JwkDidResolver(), - new PolygonDidResolver() + new PolygonDidResolver(), ], }), @@ -273,7 +273,10 @@ const getModules = ( }), openId4VcHolderModule: new OpenId4VcHolderModule(), x509: new X509Module({ - getTrustedCertificatesForVerification: async (agentContext, { certificateChain: _certificateChain, verification: _verification }) => { + getTrustedCertificatesForVerification: async ( + agentContext, + { certificateChain: _certificateChain, verification: _verification }, + ) => { //TODO: We need to trust the certificate tenant wise, for that we need to fetch those details from platform const tenantId = agentContext.contextCorrelationId console.log('[getTrustedCertificatesForVerification] tenantId from agentContext:', tenantId) diff --git a/src/controllers/auth/AuthController.ts b/src/controllers/auth/AuthController.ts index 2a26cacb..eba1e892 100644 --- a/src/controllers/auth/AuthController.ts +++ b/src/controllers/auth/AuthController.ts @@ -43,7 +43,7 @@ export class AuthController extends Controller { return response.data } -// TODO: Remove these test endpoints after manual testing is done + // TODO: Remove these test endpoints after manual testing is done @Get('/test/dedicated-x509-certificates') public async testFetchDedicatedX509Certificates(@Request() _request: Req): Promise { return fetchDedicatedX509Certificates() diff --git a/src/controllers/didcomm/connections/ConnectionController.ts b/src/controllers/didcomm/connections/ConnectionController.ts index 7c6fa5c2..6e7e7ed9 100644 --- a/src/controllers/didcomm/connections/ConnectionController.ts +++ b/src/controllers/didcomm/connections/ConnectionController.ts @@ -134,8 +134,7 @@ export class ConnectionController extends Controller { try { const outOfBandRecord = await request.agent.modules.didcomm.connections.findByInvitationDid(invitationId) - if (!outOfBandRecord) - throw new NotFoundError(`connection with invitationId "${invitationId}" not found.`) + if (!outOfBandRecord) throw new NotFoundError(`connection with invitationId "${invitationId}" not found.`) return outOfBandRecord } catch (error) { diff --git a/src/controllers/didcomm/outofband/OutOfBandController.ts b/src/controllers/didcomm/outofband/OutOfBandController.ts index 22aab3d6..2923668d 100644 --- a/src/controllers/didcomm/outofband/OutOfBandController.ts +++ b/src/controllers/didcomm/outofband/OutOfBandController.ts @@ -1,20 +1,15 @@ import type { OutOfBandInvitationProps, OutOfBandRecordWithInvitationProps } from '../../examples' import type { RecipientKeyOption, CreateInvitationOptions, AgentMessageType } from '../../types' -import type { - PeerDidNumAlgo2CreateOptions, -} from '@credo-ts/core' +import type { PeerDidNumAlgo2CreateOptions } from '@credo-ts/core' -import { - createPeerDidDocumentFromServices, - JsonTransformer, - PeerDidNumAlgo, -} from '@credo-ts/core' +import { createPeerDidDocumentFromServices, JsonTransformer, PeerDidNumAlgo } from '@credo-ts/core' import { DidCommConnectionRecordProps, DidCommRouting, DidCommOutOfBandInvitation, - DidCommMessage} from '@credo-ts/didcomm' + DidCommMessage, +} from '@credo-ts/didcomm' import { Request as Req } from 'express' import { Body, Controller, Delete, Example, Get, Path, Post, Query, Route, Tags, Security, Request } from 'tsoa' import { injectable } from 'tsyringe' @@ -94,8 +89,7 @@ export class OutOfBandController extends Controller { let invitationDid: string | undefined if (config?.invitationDid) { invitationDid = config?.invitationDid - } - else { + } else { const didRouting = await request.agent.modules.didcomm.mediationRecipient.getRouting({}) const { didDocument, keys } = createPeerDidDocumentFromServices( [ @@ -113,7 +107,7 @@ export class OutOfBandController extends Controller { method: 'peer', options: { numAlgo: PeerDidNumAlgo.MultipleInceptionKeyWithoutDoc, - keys + keys, }, }) @@ -159,9 +153,9 @@ export class OutOfBandController extends Controller { @Body() config: { recordId: string - message: Record; - domain: string, - routing?: DidCommRouting; + message: Record + domain: string + routing?: DidCommRouting }, ) { try { @@ -193,8 +187,14 @@ export class OutOfBandController extends Controller { const { invitation, ...config } = invitationRequest try { - const invite = new DidCommOutOfBandInvitation({ ...invitation, handshakeProtocols: invitation.handshake_protocols }) - const { outOfBandRecord, connectionRecord } = await request.agent.modules.didcomm.oob.receiveInvitation(invite, config) + const invite = new DidCommOutOfBandInvitation({ + ...invitation, + handshakeProtocols: invitation.handshake_protocols, + }) + const { outOfBandRecord, connectionRecord } = await request.agent.modules.didcomm.oob.receiveInvitation( + invite, + config, + ) return { outOfBandRecord: outOfBandRecord.toJSON(), diff --git a/src/controllers/openid4vc/examples/issuer.examples.ts b/src/controllers/openid4vc/examples/issuer.examples.ts index 1d5885da..5b3c9b79 100644 --- a/src/controllers/openid4vc/examples/issuer.examples.ts +++ b/src/controllers/openid4vc/examples/issuer.examples.ts @@ -1,111 +1,118 @@ export const OpenId4VcUpdateIssuerRecordOptionsExample = { withScope: { value: { - issuerId: "abc-gov", - accessTokenSignerKeyType: "ed25519", + issuerId: 'abc-gov', + accessTokenSignerKeyType: 'ed25519', display: [ { - name: "ABC Gov", - locale: "en", + name: 'ABC Gov', + locale: 'en', logo: { - uri: "https://upload.wikimedia.org/wikipedia/commons/2/2f/ABC-2021-LOGO.svg", - alt_text: "abc_logo", + uri: 'https://upload.wikimedia.org/wikipedia/commons/2/2f/ABC-2021-LOGO.svg', + alt_text: 'abc_logo', }, }, ], - dpopSigningAlgValuesSupported: ["RS256", "ES256"], + dpopSigningAlgValuesSupported: ['RS256', 'ES256'], credentialConfigurationsSupported: { - "VaccinationCredential-sdjwt": { - format: "vc+sd-jwt", - vct: "VaccinationCredential", - scope: "openid4vc:credential:VaccinationCredential-sdjwt", + 'VaccinationCredential-sdjwt': { + format: 'vc+sd-jwt', + vct: 'VaccinationCredential', + scope: 'openid4vc:credential:VaccinationCredential-sdjwt', claims: { - name: { mandatory: true, value_type: "string", display: { name: "Full Name", locale: "en" } }, - vaccine: { mandatory: true, value_type: "string", display: { name: "Vaccine Type", locale: "en" } }, - lotNumber: { value_type: "string", display: { name: "Batch Number", locale: "en" } }, - performer: { value_type: "string", display: { name: "Healthcare Provider", locale: "en" } }, - doseDate: { value_type: "date", display: { name: "Date of Dose", locale: "en" } } + name: { mandatory: true, value_type: 'string', display: { name: 'Full Name', locale: 'en' } }, + vaccine: { mandatory: true, value_type: 'string', display: { name: 'Vaccine Type', locale: 'en' } }, + lotNumber: { value_type: 'string', display: { name: 'Batch Number', locale: 'en' } }, + performer: { value_type: 'string', display: { name: 'Healthcare Provider', locale: 'en' } }, + doseDate: { value_type: 'date', display: { name: 'Date of Dose', locale: 'en' } }, }, - credential_signing_alg_values_supported: ["ES256"], - cryptographic_binding_methods_supported: ["did:key"], + credential_signing_alg_values_supported: ['ES256'], + cryptographic_binding_methods_supported: ['did:key'], display: [ { - name: "COVID-19 Vaccination Certificate", - description: "Proof of vaccination against COVID-19", - locale: "en" - } - ] + name: 'COVID-19 Vaccination Certificate', + description: 'Proof of vaccination against COVID-19', + locale: 'en', + }, + ], }, - "NationalIDCredential-mdoc": { - format: "mso_mdoc", - doctype: "org.iso.18013.5.1", - scope: "openid4vc:credential:NationalIDCredential-mdoc", + 'NationalIDCredential-mdoc': { + format: 'mso_mdoc', + doctype: 'org.iso.18013.5.1', + scope: 'openid4vc:credential:NationalIDCredential-mdoc', claims: { - family_name: { mandatory: true, value_type: "string", display: { name: "Last Name", locale: "en" } }, - given_name: { mandatory: true, value_type: "string", display: { name: "First Name", locale: "en" } }, - birth_date: { value_type: "date", display: { name: "Date of Birth", locale: "en" } }, - gender: { value_type: "string", display: { name: "Gender", locale: "en" } }, - nationality: { value_type: "string", display: { name: "Nationality", locale: "en" } }, - document_number: { mandatory: true, value_type: "string", display: { name: "Document Number", locale: "en" } }, - issuing_authority: { value_type: "string", display: { name: "Issuing Authority", locale: "en" } }, - expiry_date: { value_type: "date", display: { name: "Expiry Date", locale: "en" } } + family_name: { mandatory: true, value_type: 'string', display: { name: 'Last Name', locale: 'en' } }, + given_name: { mandatory: true, value_type: 'string', display: { name: 'First Name', locale: 'en' } }, + birth_date: { value_type: 'date', display: { name: 'Date of Birth', locale: 'en' } }, + gender: { value_type: 'string', display: { name: 'Gender', locale: 'en' } }, + nationality: { value_type: 'string', display: { name: 'Nationality', locale: 'en' } }, + document_number: { + mandatory: true, + value_type: 'string', + display: { name: 'Document Number', locale: 'en' }, + }, + issuing_authority: { value_type: 'string', display: { name: 'Issuing Authority', locale: 'en' } }, + expiry_date: { value_type: 'date', display: { name: 'Expiry Date', locale: 'en' } }, }, - credential_signing_alg_values_supported: ["ES256"], - cryptographic_binding_methods_supported: ["did:key"], + credential_signing_alg_values_supported: ['ES256'], + cryptographic_binding_methods_supported: ['did:key'], display: [ { - name: "National ID", - description: "Digital government-issued identity credential", - locale: "en" - } - ] + name: 'National ID', + description: 'Digital government-issued identity credential', + locale: 'en', + }, + ], }, - "UniversityDegreeCredential-sdjwt": { - format: "vc+sd-jwt", - vct: "UniversityDegreeCredential", - scope: "openid4vc:credential:UniversityDegreeCredential-sdjwt", + 'UniversityDegreeCredential-sdjwt': { + format: 'vc+sd-jwt', + vct: 'UniversityDegreeCredential', + scope: 'openid4vc:credential:UniversityDegreeCredential-sdjwt', claims: { - full_name: { mandatory: true, value_type: "string", display: { name: "Full Name", locale: "en" } }, - diploma_name: { mandatory: true, value_type: "string", display: { name: "Degree Title", locale: "en" } }, - college_name: { value_type: "string", display: { name: "College/University", locale: "en" } }, - graduation_date: { value_type: "date", display: { name: "Graduation Date", locale: "en" } }, - awarded_date: { value_type: "date", display: { name: "Award Date", locale: "en" } } + full_name: { mandatory: true, value_type: 'string', display: { name: 'Full Name', locale: 'en' } }, + diploma_name: { mandatory: true, value_type: 'string', display: { name: 'Degree Title', locale: 'en' } }, + college_name: { value_type: 'string', display: { name: 'College/University', locale: 'en' } }, + graduation_date: { value_type: 'date', display: { name: 'Graduation Date', locale: 'en' } }, + awarded_date: { value_type: 'date', display: { name: 'Award Date', locale: 'en' } }, }, - credential_signing_alg_values_supported: ["ES256", "EdDSA"], - cryptographic_binding_methods_supported: ["did:key"], + credential_signing_alg_values_supported: ['ES256', 'EdDSA'], + cryptographic_binding_methods_supported: ['did:key'], display: [ { - name: "University Degree Credential", - description: "Issued by a recognized educational institution", - locale: "en" - } - ] + name: 'University Degree Credential', + description: 'Issued by a recognized educational institution', + locale: 'en', + }, + ], }, - "DrivingLicenseCredential-mdoc": { - format: "mso_mdoc", - doctype: "org.iso.18013.5.1", - scope: "openid4vc:credential:DrivingLicenseCredential-mdoc", + 'DrivingLicenseCredential-mdoc': { + format: 'mso_mdoc', + doctype: 'org.iso.18013.5.1', + scope: 'openid4vc:credential:DrivingLicenseCredential-mdoc', claims: { - family_name: { mandatory: true, value_type: "string", display: { name: "Surname", locale: "en" } }, - given_name: { mandatory: true, value_type: "string", display: { name: "Given Name", locale: "en" } }, - birth_date: { value_type: "date", display: { name: "Date of Birth", locale: "en" } }, - issue_date: { value_type: "date", display: { name: "Issued On", locale: "en" } }, - expiry_date: { value_type: "date", display: { name: "Expires On", locale: "en" } }, - issuing_country: { value_type: "string", display: { name: "Issuing Country", locale: "en" } }, - license_number: { value_type: "string", display: { name: "License Number", locale: "en" } }, - categories_of_vehicles: { value_type: "string", display: { name: "Authorized Vehicle Types", locale: "en" } } + family_name: { mandatory: true, value_type: 'string', display: { name: 'Surname', locale: 'en' } }, + given_name: { mandatory: true, value_type: 'string', display: { name: 'Given Name', locale: 'en' } }, + birth_date: { value_type: 'date', display: { name: 'Date of Birth', locale: 'en' } }, + issue_date: { value_type: 'date', display: { name: 'Issued On', locale: 'en' } }, + expiry_date: { value_type: 'date', display: { name: 'Expires On', locale: 'en' } }, + issuing_country: { value_type: 'string', display: { name: 'Issuing Country', locale: 'en' } }, + license_number: { value_type: 'string', display: { name: 'License Number', locale: 'en' } }, + categories_of_vehicles: { + value_type: 'string', + display: { name: 'Authorized Vehicle Types', locale: 'en' }, + }, }, - credential_signing_alg_values_supported: ["ES256"], - cryptographic_binding_methods_supported: ["did:key"], + credential_signing_alg_values_supported: ['ES256'], + cryptographic_binding_methods_supported: ['did:key'], display: [ { - name: "Driving License", - description: "ISO-compliant mobile driving license", - locale: "en" - } - ] - } - } - } - } -}; + name: 'Driving License', + description: 'ISO-compliant mobile driving license', + locale: 'en', + }, + ], + }, + }, + }, + }, +} diff --git a/src/errorHandlingService.ts b/src/errorHandlingService.ts index 317ee472..b3ad6aa4 100644 --- a/src/errorHandlingService.ts +++ b/src/errorHandlingService.ts @@ -1,12 +1,7 @@ import type { BaseError } from './errors/errors' import { AnonCredsError, AnonCredsRsError, AnonCredsStoreRecordError } from '@credo-ts/anoncreds' -import { - CredoError, - RecordNotFoundError, - RecordDuplicateError, - ClassValidationError -} from '@credo-ts/core' +import { CredoError, RecordNotFoundError, RecordDuplicateError, ClassValidationError } from '@credo-ts/core' import { MessageSendingError } from '@credo-ts/didcomm' import { IndyVdrError } from '@hyperledger/indy-vdr-nodejs' diff --git a/src/events/BasicMessageEvents.ts b/src/events/BasicMessageEvents.ts index 93470d64..e064995e 100644 --- a/src/events/BasicMessageEvents.ts +++ b/src/events/BasicMessageEvents.ts @@ -1,29 +1,32 @@ import type { ServerConfig } from '../utils/ServerConfig' import type { Agent } from '@credo-ts/core' -import { DidCommBasicMessageEventTypes,DidCommBasicMessageStateChangedEvent } from '@credo-ts/didcomm' +import { DidCommBasicMessageEventTypes, DidCommBasicMessageStateChangedEvent } from '@credo-ts/didcomm' import { sendWebSocketEvent } from './WebSocketEvents' import { sendWebhookEvent } from './WebhookEvent' export const basicMessageEvents = async (agent: Agent, config: ServerConfig) => { - agent.events.on(DidCommBasicMessageEventTypes.DidCommBasicMessageStateChanged, async (event: DidCommBasicMessageStateChangedEvent) => { - const record = event.payload.basicMessageRecord - const body = record.toJSON() + agent.events.on( + DidCommBasicMessageEventTypes.DidCommBasicMessageStateChanged, + async (event: DidCommBasicMessageStateChangedEvent) => { + const record = event.payload.basicMessageRecord + const body = record.toJSON() - // Only send webhook if webhook url is configured - if (config.webhookUrl) { - await sendWebhookEvent(config.webhookUrl + '/basic-messages', body, agent.config.logger) - } + // Only send webhook if webhook url is configured + if (config.webhookUrl) { + await sendWebhookEvent(config.webhookUrl + '/basic-messages', body, agent.config.logger) + } - if (config.socketServer) { - // Always emit websocket event to clients (could be 0) - sendWebSocketEvent(config.socketServer, { - ...event, - payload: { - message: event.payload.message.toJSON(), - basicMessageRecord: body, - }, - }) - } - }) + if (config.socketServer) { + // Always emit websocket event to clients (could be 0) + sendWebSocketEvent(config.socketServer, { + ...event, + payload: { + message: event.payload.message.toJSON(), + basicMessageRecord: body, + }, + }) + } + }, + ) } diff --git a/src/events/ConnectionEvents.ts b/src/events/ConnectionEvents.ts index ae8cda39..7a67a7d2 100644 --- a/src/events/ConnectionEvents.ts +++ b/src/events/ConnectionEvents.ts @@ -7,24 +7,27 @@ import { sendWebSocketEvent } from './WebSocketEvents' import { sendWebhookEvent } from './WebhookEvent' export const connectionEvents = async (agent: Agent, config: ServerConfig) => { - agent.events.on(DidCommConnectionEventTypes.DidCommConnectionStateChanged, async (event: DidCommConnectionStateChangedEvent) => { - const record = event.payload.connectionRecord - const body = { ...record.toJSON(), ...event.metadata } + agent.events.on( + DidCommConnectionEventTypes.DidCommConnectionStateChanged, + async (event: DidCommConnectionStateChangedEvent) => { + const record = event.payload.connectionRecord + const body = { ...record.toJSON(), ...event.metadata } - // Only send webhook if webhook url is configured - if (config.webhookUrl) { - await sendWebhookEvent(config.webhookUrl + '/connections', body, agent.config.logger) - } + // Only send webhook if webhook url is configured + if (config.webhookUrl) { + await sendWebhookEvent(config.webhookUrl + '/connections', body, agent.config.logger) + } - if (config.socketServer) { - // Always emit websocket event to clients (could be 0) - sendWebSocketEvent(config.socketServer, { - ...event, - payload: { - ...event.payload, - connectionRecord: body, - }, - }) - } - }) + if (config.socketServer) { + // Always emit websocket event to clients (could be 0) + sendWebSocketEvent(config.socketServer, { + ...event, + payload: { + ...event.payload, + connectionRecord: body, + }, + }) + } + }, + ) } diff --git a/src/events/CredentialEvents.ts b/src/events/CredentialEvents.ts index d9b8cf14..080ecf6d 100644 --- a/src/events/CredentialEvents.ts +++ b/src/events/CredentialEvents.ts @@ -8,37 +8,40 @@ import { sendWebSocketEvent } from './WebSocketEvents' import { sendWebhookEvent } from './WebhookEvent' export const credentialEvents = async (agent: Agent, config: ServerConfig) => { - agent.events.on(DidCommCredentialEventTypes.DidCommCredentialStateChanged, async (event: DidCommCredentialStateChangedEvent) => { - const record = event.payload.credentialExchangeRecord - - const body: Record = { - ...record.toJSON(), - ...event.metadata, - outOfBandId: null, - credentialData: null, - } - - if (record?.connectionId) { - const connectionRecord = await agent.modules.connections.findById(record.connectionId!) - body.outOfBandId = connectionRecord?.outOfBandId - } - - const data = await agent.modules.credentials.getFormatData(record.id) - body.credentialData = data - - if (config.webhookUrl) { - await sendWebhookEvent(config.webhookUrl + '/credentials', body, agent.config.logger) - } - - if (config.socketServer) { - // Always emit websocket event to clients (could be 0) - sendWebSocketEvent(config.socketServer, { - ...event, - payload: { - ...event.payload, - credentialRecord: body, - }, - }) - } - }) + agent.events.on( + DidCommCredentialEventTypes.DidCommCredentialStateChanged, + async (event: DidCommCredentialStateChangedEvent) => { + const record = event.payload.credentialExchangeRecord + + const body: Record = { + ...record.toJSON(), + ...event.metadata, + outOfBandId: null, + credentialData: null, + } + + if (record?.connectionId) { + const connectionRecord = await agent.modules.connections.findById(record.connectionId!) + body.outOfBandId = connectionRecord?.outOfBandId + } + + const data = await agent.modules.credentials.getFormatData(record.id) + body.credentialData = data + + if (config.webhookUrl) { + await sendWebhookEvent(config.webhookUrl + '/credentials', body, agent.config.logger) + } + + if (config.socketServer) { + // Always emit websocket event to clients (could be 0) + sendWebSocketEvent(config.socketServer, { + ...event, + payload: { + ...event.payload, + credentialRecord: body, + }, + }) + } + }, + ) } diff --git a/src/events/ProofEvents.ts b/src/events/ProofEvents.ts index ad961675..44166f62 100644 --- a/src/events/ProofEvents.ts +++ b/src/events/ProofEvents.ts @@ -1,5 +1,5 @@ import type { ServerConfig } from '../utils/ServerConfig' -import type { Agent, } from '@credo-ts/core' +import type { Agent } from '@credo-ts/core' import { DidCommProofStateChangedEvent, DidCommProofEventTypes } from '@credo-ts/didcomm' import { sendWebSocketEvent } from './WebSocketEvents' diff --git a/src/events/WebSocketEvents.ts b/src/events/WebSocketEvents.ts index 358ca800..e3f1b00f 100644 --- a/src/events/WebSocketEvents.ts +++ b/src/events/WebSocketEvents.ts @@ -1,4 +1,4 @@ -import {Server} from 'ws' +import { Server } from 'ws' export const sendWebSocketEvent = async (server: Server, data: unknown) => { server.clients.forEach((client) => { diff --git a/src/events/openId4VcIssuanceSessionEvents.ts b/src/events/openId4VcIssuanceSessionEvents.ts index 291331a0..18267b1b 100644 --- a/src/events/openId4VcIssuanceSessionEvents.ts +++ b/src/events/openId4VcIssuanceSessionEvents.ts @@ -7,23 +7,26 @@ import { OpenId4VcIssuerEvents } from '@credo-ts/openid4vc' import type { OpenId4VcIssuanceSessionStateChangedEvent } from '@credo-ts/openid4vc' export const openId4VcIssuanceSessionEvents = async (agent: Agent, config: ServerConfig) => { - agent.events.on(OpenId4VcIssuerEvents.IssuanceSessionStateChanged, async (event: OpenId4VcIssuanceSessionStateChangedEvent) => { - const record = event.payload.issuanceSession + agent.events.on( + OpenId4VcIssuerEvents.IssuanceSessionStateChanged, + async (event: OpenId4VcIssuanceSessionStateChangedEvent) => { + const record = event.payload.issuanceSession - const body = { ...record.toJSON(), ...event.metadata } + const body = { ...record.toJSON(), ...event.metadata } - if (config.webhookUrl) { - await sendWebhookEvent(config.webhookUrl + '/openid4vc-issuance', body, agent.config.logger) - } + if (config.webhookUrl) { + await sendWebhookEvent(config.webhookUrl + '/openid4vc-issuance', body, agent.config.logger) + } - if (config.socketServer) { - sendWebSocketEvent(config.socketServer, { - ...event, - payload: { - ...event.payload, - issuanceRecord: body, - }, - }) - } - }) + if (config.socketServer) { + sendWebSocketEvent(config.socketServer, { + ...event, + payload: { + ...event.payload, + issuanceRecord: body, + }, + }) + } + }, + ) } diff --git a/src/events/openId4VcVerificationSessionEvents.ts b/src/events/openId4VcVerificationSessionEvents.ts index 4643b44d..50fbdf03 100644 --- a/src/events/openId4VcVerificationSessionEvents.ts +++ b/src/events/openId4VcVerificationSessionEvents.ts @@ -6,22 +6,25 @@ import { sendWebhookEvent } from './WebhookEvent' import { OpenId4VcVerificationSessionStateChangedEvent, OpenId4VcVerifierEvents } from '@credo-ts/openid4vc' export const openId4VcVerificationSessionEvents = async (agent: Agent, config: ServerConfig) => { - agent.events.on(OpenId4VcVerifierEvents.VerificationSessionStateChanged, async (event: OpenId4VcVerificationSessionStateChangedEvent) => { - const record = event.payload.verificationSession - const body = { ...record.toJSON(), ...event.metadata } + agent.events.on( + OpenId4VcVerifierEvents.VerificationSessionStateChanged, + async (event: OpenId4VcVerificationSessionStateChangedEvent) => { + const record = event.payload.verificationSession + const body = { ...record.toJSON(), ...event.metadata } - if (config.webhookUrl) { - await sendWebhookEvent(config.webhookUrl + '/openid4vc-verification', body, agent.config.logger) - } + if (config.webhookUrl) { + await sendWebhookEvent(config.webhookUrl + '/openid4vc-verification', body, agent.config.logger) + } - if (config.socketServer) { - sendWebSocketEvent(config.socketServer, { - ...event, - payload: { - ...event.payload, - verificationRecord: body, - }, - }) - } - }) + if (config.socketServer) { + sendWebSocketEvent(config.socketServer, { + ...event, + payload: { + ...event.payload, + verificationRecord: body, + }, + }) + } + }, + ) } diff --git a/src/types/request.d.ts b/src/types/request.d.ts index c14cad9b..a5223399 100644 --- a/src/types/request.d.ts +++ b/src/types/request.d.ts @@ -2,7 +2,6 @@ import type { RestAgentModules, RestMultiTenantAgentModules } from '../cliAgent' import type { Agent } from '@credo-ts/core' import type { TenantAgent } from '@credo-ts/tenants' - type AgentType = Agent | Agent | TenantAgent interface IAgent { @@ -16,4 +15,3 @@ declare global { } } } - diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 8338592a..ef33bafc 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -94,7 +94,12 @@ export function getTypeFromCurve(key: Curve | KeyAlgorithm): OkpType | EcType { return keyTypeInfo } -async function fetchPlatformToken(platformBaseUrl: string, clientId: string, clientSecret: string, label: string): Promise { +async function fetchPlatformToken( + platformBaseUrl: string, + clientId: string, + clientSecret: string, + label: string, +): Promise { if (!platformBaseUrl) throw new Error(`[${label}] platformBaseUrl is required`) if (!clientId) throw new Error(`[${label}] clientId is required`) if (!clientSecret) throw new Error(`[${label}] clientSecret is required`) @@ -137,7 +142,12 @@ async function fetchPlatformToken(platformBaseUrl: string, clientId: string, cli return token } -async function fetchTrustServiceCertificates(trustServiceUrl: string, token: string, ecosystemIds: string[], label: string): Promise { +async function fetchTrustServiceCertificates( + trustServiceUrl: string, + token: string, + ecosystemIds: string[], + label: string, +): Promise { const certsUrl = `${trustServiceUrl}/api/x509-certificates/ecosystems` console.log(`[${label}] fetching certificates from:`, certsUrl, 'ecosystemIds:', ecosystemIds) @@ -166,7 +176,9 @@ async function fetchTrustServiceCertificates(trustServiceUrl: string, token: str data: error.response?.data, message: error.message, }) - throw new Error(`Failed to fetch certificates from trust-service: ${error.response?.status} ${JSON.stringify(error.response?.data)}`) + throw new Error( + `Failed to fetch certificates from trust-service: ${error.response?.status} ${JSON.stringify(error.response?.data)}`, + ) } throw error } @@ -201,7 +213,7 @@ export async function fetchSharedAgentX509Certificates(tenantId?: string): Promi if (!clientSecret) throw new Error('PLATFORM_SHARED_AGENT_CLIENT_SECRET is not configured') if (!resolvedTenantId) throw new Error('tenantId not provided and PLATFORM_SHARED_AGENT_TENANT_ID is not configured') if (!trustServiceUrl) throw new Error('TRUST_SERVICE_URL is not configured') - console.log(`[${label}] starting certificate fetch for tenantId:`, resolvedTenantId) + console.log(`[${label}] starting certificate fetch for tenantId:`, resolvedTenantId) console.log(`[${label}] using tenantId:`, resolvedTenantId, tenantId ? '(from agent context)' : '(from .env)') @@ -212,10 +224,9 @@ export async function fetchSharedAgentX509Certificates(tenantId?: string): Promi let ecosystemIds: string[] try { - const ecosystemResponse = await axios.get<{ statusCode: number; message: string; data: string[] }>( - ecosystemsUrl, - { headers: { accept: 'application/json', Authorization: `Bearer ${token}` } }, - ) + const ecosystemResponse = await axios.get<{ statusCode: number; message: string; data: string[] }>(ecosystemsUrl, { + headers: { accept: 'application/json', Authorization: `Bearer ${token}` }, + }) console.log(`[${label}] ecosystem response status:`, ecosystemResponse.status) console.log(`[${label}] ecosystem response data:`, JSON.stringify(ecosystemResponse.data, null, 2)) @@ -234,7 +245,9 @@ export async function fetchSharedAgentX509Certificates(tenantId?: string): Promi data: error.response?.data, message: error.message, }) - throw new Error(`Failed to fetch ecosystem IDs from platform: ${error.response?.status} ${JSON.stringify(error.response?.data)}`) + throw new Error( + `Failed to fetch ecosystem IDs from platform: ${error.response?.status} ${JSON.stringify(error.response?.data)}`, + ) } throw error } diff --git a/src/utils/oid4vc-agent.ts b/src/utils/oid4vc-agent.ts index 6acbf823..850f604d 100644 --- a/src/utils/oid4vc-agent.ts +++ b/src/utils/oid4vc-agent.ts @@ -256,9 +256,9 @@ export async function getTrustedCerts(tenantId?: string): Promise { console.warn('[getTrustedCerts] no certificates returned') return [] } -// Remove this log after testing to avoid logging sensitive certificate information + // Remove this log after testing to avoid logging sensitive certificate information console.log('[getTrustedCerts] fetched certificates count:', certs.length) - console.log("certs::::::::::::::::::::::::::", certs) + console.log('certs::::::::::::::::::::::::::', certs) return certs } catch (error) { console.error('[getTrustedCerts] failed:', error instanceof Error ? error.message : error) From e2dc9110bc5c6bbc32b8147f8f59fa6cb846b27a Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Thu, 5 Mar 2026 19:08:06 +0530 Subject: [PATCH 4/6] fix: polygon controller Signed-off-by: Krishna Waske --- src/controllers/polygon/PolygonController.ts | 277 ++++++++++--------- 1 file changed, 139 insertions(+), 138 deletions(-) diff --git a/src/controllers/polygon/PolygonController.ts b/src/controllers/polygon/PolygonController.ts index e889e2b7..db5faa8b 100644 --- a/src/controllers/polygon/PolygonController.ts +++ b/src/controllers/polygon/PolygonController.ts @@ -1,146 +1,147 @@ -// import type { SchemaMetadata } from '../types' +import type { SchemaMetadata } from '../types' -// import { generateSecp256k1KeyPair } from '@ayanworks/credo-polygon-w3c-module' -// // import { DidOperation, DidOperationOptions } from '@ayanworks/credo-polygon-w3c-module' -// import { Request as Req } from 'express' -// import * as fs from 'fs' -// import { Route, Tags, Security, Controller, Post, Body, Get, Path, Request } from 'tsoa' -// import { injectable } from 'tsyringe' +import { generateSecp256k1KeyPair } from '@ayanworks/credo-polygon-w3c-module' +import { Request as Req } from 'express' +import * as fs from 'fs' +import { Route, Tags, Security, Controller, Post, Body, Get, Path, Request } from 'tsoa' +import { injectable } from 'tsyringe' -// import { CredentialEnum, SCOPES } from '../../enums' -// import ErrorHandlingService from '../../errorHandlingService' -// import { BadRequestError, UnprocessableEntityError } from '../../errors' +import { CredentialEnum, SCOPES } from '../../enums' +import ErrorHandlingService from '../../errorHandlingService' +import { BadRequestError, UnprocessableEntityError } from '../../errors' +import { DidOperation, DidOperationOptions } from '@ayanworks/credo-polygon-w3c-module' -// @Tags('Polygon') -// @Route('/polygon') -// @injectable() -// export class Polygon extends Controller { -// /** -// * Create Secp256k1 key pair for polygon DID -// * -// * @returns Secp256k1KeyPair -// */ -// @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT, SCOPES.MULTITENANT_BASE_AGENT]) -// @Post('create-keys') -// public async createKeyPair(): Promise<{ -// privateKey: string -// publicKeyBase58: string -// address: string -// }> { -// try { -// return await generateSecp256k1KeyPair() -// } catch (error) { -// // Handle the error here -// throw ErrorHandlingService.handle(error) -// } -// } +@Tags('Polygon') +@Route('/polygon') +@injectable() +export class Polygon extends Controller { + /** + * Create Secp256k1 key pair for polygon DID + * + * @returns Secp256k1KeyPair + */ + @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT, SCOPES.MULTITENANT_BASE_AGENT]) + @Post('create-keys') + public async createKeyPair(): Promise<{ + privateKey: string + publicKeyBase58: string + address: string + }> { + try { + return await generateSecp256k1KeyPair() + } catch (error) { + // Handle the error here + throw ErrorHandlingService.handle(error) + } + } -// /** -// * Create polygon based W3C schema -// * -// * @returns Schema JSON -// */ -// @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) -// @Post('create-schema') -// public async createSchema( -// @Request() request: Req, -// @Body() -// createSchemaRequest: { -// did: string -// schemaName: string -// schema: Record -// }, -// ): Promise { -// try { -// const { did, schemaName, schema } = createSchemaRequest -// if (!did || !schemaName || !schema) { -// throw new BadRequestError('One or more parameters are empty or undefined.') -// } + /** + * Create polygon based W3C schema + * + * @returns Schema JSON + */ + // TODO: Fix the schema creation issue, caused by not able to find the `did` based on the key-name. + // Right now, the key-id is assumed to be the base58publicKey. But its not. Need to fix it + // @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) + // @Post('create-schema') + // public async createSchema( + // @Request() request: Req, + // @Body() + // createSchemaRequest: { + // did: string + // schemaName: string + // schema: Record + // }, + // ): Promise { + // try { + // const { did, schemaName, schema } = createSchemaRequest + // if (!did || !schemaName || !schema) { + // throw new BadRequestError('One or more parameters are empty or undefined.') + // } -// const schemaResponse = await request.agent.modules.polygon.createSchema({ -// did, -// schemaName, -// schema, -// }) -// if (schemaResponse.schemaState?.state === CredentialEnum.Failed) { -// const reason = schemaResponse.schemaState?.reason?.toLowerCase() -// if (reason && reason.includes('insufficient') && reason.includes('funds')) { -// throw new UnprocessableEntityError( -// 'Insufficient funds to the address, Please add funds to perform this operation', -// ) -// } else { -// throw new Error(schemaResponse.schemaState?.reason) -// } -// } -// const schemaServerConfig = fs.readFileSync('config.json', 'utf-8') -// const configJson = JSON.parse(schemaServerConfig) -// if (!configJson.schemaFileServerURL) { -// throw new Error('Please provide valid schema file server URL') -// } + // const schemaResponse = await request.agent.modules.polygon.createSchema({ + // did, + // schemaName, + // schema, + // }) + // if (schemaResponse.schemaState?.state === CredentialEnum.Failed) { + // const reason = schemaResponse.schemaState?.reason?.toLowerCase() + // if (reason && reason.includes('insufficient') && reason.includes('funds')) { + // throw new UnprocessableEntityError( + // 'Insufficient funds to the address, Please add funds to perform this operation', + // ) + // } else { + // throw new Error(schemaResponse.schemaState?.reason) + // } + // } + // const schemaServerConfig = fs.readFileSync('config.json', 'utf-8') + // const configJson = JSON.parse(schemaServerConfig) + // if (!configJson.schemaFileServerURL) { + // throw new Error('Please provide valid schema file server URL') + // } -// if (!schemaResponse?.schemaId) { -// throw new BadRequestError('Error in getting schema response or Invalid schema response') -// } -// const schemaPayload: SchemaMetadata = { -// schemaUrl: configJson.schemaFileServerURL + schemaResponse?.schemaId, -// did: schemaResponse?.did, -// schemaId: schemaResponse?.schemaId, -// schemaTxnHash: schemaResponse?.resourceTxnHash, -// } -// return schemaPayload -// } catch (error) { -// throw ErrorHandlingService.handle(error) -// } -// } + // if (!schemaResponse?.schemaId) { + // throw new BadRequestError('Error in getting schema response or Invalid schema response') + // } + // const schemaPayload: SchemaMetadata = { + // schemaUrl: configJson.schemaFileServerURL + schemaResponse?.schemaId, + // did: schemaResponse?.did, + // schemaId: schemaResponse?.schemaId, + // schemaTxnHash: schemaResponse?.resourceTxnHash, + // } + // return schemaPayload + // } catch (error) { + // throw ErrorHandlingService.handle(error) + // } + // } -// // /** -// // * Estimate transaction -// // * -// // * @returns Transaction Object -// // */ -// // @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT, SCOPES.MULTITENANT_BASE_AGENT]) -// // @Post('estimate-transaction') -// // public async estimateTransaction( -// // @Request() request: Req, -// // @Body() -// // estimateTransactionRequest: DidOperationOptions, -// // ): Promise { -// // try { -// // const { operation } = estimateTransactionRequest + /** + * Estimate transaction + * + * @returns Transaction Object + */ + @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT, SCOPES.MULTITENANT_BASE_AGENT]) + @Post('estimate-transaction') + public async estimateTransaction( + @Request() request: Req, + @Body() + estimateTransactionRequest: DidOperationOptions, + ): Promise { + try { + const { operation } = estimateTransactionRequest + if (!Object.values(DidOperation).includes(operation)) { + throw new BadRequestError('Invalid method parameter!') + } + if (operation === DidOperation.Create) { + return request.agent.modules.polygon.estimateFeeForDidOperation({ operation }) + } else if (operation === DidOperation.Update) { + return request.agent.modules.polygon.estimateFeeForDidOperation({ ...estimateTransactionRequest }) + } + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } -// // if (!(operation in DidOperation)) { -// // throw new BadRequestError('Invalid method parameter!') -// // } -// // if (operation === DidOperation.Create) { -// // return request.agent.modules.polygon.estimateFeeForDidOperation({ operation }) -// // } else if (operation === DidOperation.Update) { -// // return request.agent.modules.polygon.estimateFeeForDidOperation({ ...estimateTransactionRequest }) -// // } -// // } catch (error) { -// // throw ErrorHandlingService.handle(error) -// // } -// // } - -// /** -// * Fetch schema details -// * -// * @returns Schema Object -// */ -// @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) -// @Get(':did/:schemaId') -// public async getSchemaById( -// @Request() request: Req, -// @Path('did') did: string, -// @Path('schemaId') schemaId: string, -// ): Promise { -// try { -// if (!did || !schemaId) { -// throw new BadRequestError('Missing or invalid parameters.') -// } -// const schemaDetails = await request.agent.modules.polygon.getSchemaById(did, schemaId) -// return schemaDetails -// } catch (error) { -// throw ErrorHandlingService.handle(error) -// } -// } -// } + /** + * Fetch schema details + * + * @returns Schema Object + */ + @Security('jwt', [SCOPES.TENANT_AGENT, SCOPES.DEDICATED_AGENT]) + @Get(':did/:schemaId') + public async getSchemaById( + @Request() request: Req, + @Path('did') did: string, + @Path('schemaId') schemaId: string, + ): Promise { + try { + if (!did || !schemaId) { + throw new BadRequestError('Missing or invalid parameters.') + } + const schemaDetails = await request.agent.modules.polygon.getSchemaById(did, schemaId) + return schemaDetails + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } +} From 893750236a2e37b9d7d3b589a814a6d190201720 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Fri, 6 Mar 2026 12:06:37 +0530 Subject: [PATCH 5/6] fix: take polygon config from env for setupAgent Signed-off-by: Krishna Waske --- src/utils/agent.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/agent.ts b/src/utils/agent.ts index 46944c93..aebf6c49 100644 --- a/src/utils/agent.ts +++ b/src/utils/agent.ts @@ -128,11 +128,11 @@ export const setupAgent = async ({ }, }), polygon: new PolygonModule({ - didContractAddress: '', - schemaManagerContractAddress: '', - fileServerToken: '', - rpcUrl: '', - serverUrl: '', + didContractAddress: process.env.DID_CONTRACT_ADDRESS as string, + schemaManagerContractAddress: process.env.SCHEMA_MANAGER_CONTRACT_ADDRESS as string, + fileServerToken: process.env.FILE_SERVER_TOKEN as string, + rpcUrl: process.env.RPC_URL as string, + serverUrl: process.env.SERVER_URL as string, }), }, dependencies: agentDependencies, From 3e2747f6ba57b9fccce869dd27373bf7d139d837 Mon Sep 17 00:00:00 2001 From: Krishna Waske Date: Fri, 6 Mar 2026 15:33:43 +0530 Subject: [PATCH 6/6] fix: update rpc url Signed-off-by: Krishna Waske --- .env.demo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.demo b/.env.demo index 02fceaa5..aafeab62 100644 --- a/.env.demo +++ b/.env.demo @@ -13,7 +13,7 @@ INDICIO_NYM_URL=https://selfserve.indiciotech.io/nym # Contract address for Polygon (mainnet) SCHEMA_MANAGER_CONTRACT_ADDRESS=0x4B16719E73949a62E9A7306F352ec73F1B143c27 DID_CONTRACT_ADDRESS=0x0C16958c4246271622201101C83B9F0Fc7180d15 -RPC_URL=https://polygon-rpc.com +RPC_URL=https://polygon.drpc.org # Contract address for Polygon (testnet) # SCHEMA_MANAGER_CONTRACT_ADDRESS=0x4742d43C2dFCa5a1d4238240Afa8547Daf87Ee7a # DID_CONTRACT_ADDRESS=0xcB80F37eDD2bE3570c6C9D5B0888614E04E1e49E