Skip to content

Commit

Permalink
feat: support query features (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
lotharking authored Jan 24, 2025
1 parent fcf8bcb commit 8bc378d
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 10 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ COPY ./public ./public

COPY tsconfig.json tsconfig.json
COPY tsconfig.build.json tsconfig.build.json
COPY packages/main/discovery.json packages/main/discovery.json

COPY packages/model/tsconfig.json packages/model/tsconfig.json
COPY packages/model/tsconfig.build.json packages/model/tsconfig.build.json
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ but likely needed for production and test deployments.
> **Note**: While not mandatory, it is recommended to set an agent public DID matching external hostname (e.g. if your Service Agent instance is accessable in `https://myagent.com:3000` you must set AGENT_PUBLIC_DID to `did:web:myagent.com%3A3000`), which will make possible for the agent to create its own creadential types and therefore issue credentials. Note that you'll need HTTPS in order to fully support did:web specification.
>
> Public DID will be used also for agents to easily connect to it using DIDComm without the need of creating an explicit invitation by doing a GET request to `/invitation` endpoint.
>
> The Service Agent fetches capabilities from the `discovery.json` file at `/www/packages/main/discovery.json` to determine available features. To customize the capabilities, replace the volume at this path with your own `discovery.json` file. This allows flexibility for defining different capabilities.
Possible log levels:

Expand Down
6 changes: 6 additions & 0 deletions packages/main/discovery.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"featureType": "capability",
"match": "mrtd.*"
}
]
2 changes: 1 addition & 1 deletion packages/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
},
"dependencies": {
"@2060.io/credo-ts-didcomm-calls": "^0.0.10",
"@2060.io/credo-ts-didcomm-mrtd": "^0.0.10",
"@2060.io/credo-ts-didcomm-mrtd": "^0.0.12",
"@2060.io/credo-ts-didcomm-user-profile": "0.0.6",
"@2060.io/service-agent-model": "*",
"@credo-ts/action-menu": "^0.5.11",
Expand Down
46 changes: 44 additions & 2 deletions packages/main/src/events/ConnectionEvents.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import type { ServerConfig } from '../utils/ServerConfig'
import type { AgentMessageProcessedEvent, ConnectionStateChangedEvent } from '@credo-ts/core'
import type {
AgentMessageProcessedEvent,
ConnectionStateChangedEvent,
DiscoverFeaturesDisclosureReceivedEvent,
} from '@credo-ts/core'

import { ConnectionStateUpdated } from '@2060.io/service-agent-model'
import {
AgentEventTypes,
ConnectionEventTypes,
ConnectionRepository,
DidExchangeState,
DiscoverFeaturesEventTypes,
HangupMessage,
} from '@credo-ts/core'

Expand All @@ -31,8 +36,15 @@ export const connectionEvents = async (agent: ServiceAgent, config: ServerConfig
}
}

if (record.state === DidExchangeState.Completed)
if (record.state === DidExchangeState.Completed) {
await agent.modules.userProfile.requestUserProfile({ connectionId: record.id })
config.discoveryOptions &&
(await agent.discovery.queryFeatures({
connectionId: record.id,
protocolVersion: 'v2',
queries: config.discoveryOptions,
}))
}

const body = new ConnectionStateUpdated({
connectionId: record.id,
Expand All @@ -59,4 +71,34 @@ export const connectionEvents = async (agent: ServiceAgent, config: ServerConfig
await sendWebhookEvent(config.webhookUrl + '/connection-state-updated', body, config.logger)
}
})

agent.events.on(
DiscoverFeaturesEventTypes.DisclosureReceived,
async ({ payload }: DiscoverFeaturesDisclosureReceivedEvent) => {
const record = payload.connection
payload.disclosures.forEach(item =>
record.metadata.add(`features-${item.type}`, { [item.id]: item.toJSON() }),
)
await agent.context.dependencyManager
.resolve(ConnectionRepository)
.update(agent.context, payload.connection)

const metadata = payload.disclosures?.reduce(
(acc, item) => {
acc[item.id] = JSON.stringify(item.toJSON())
return acc
},
{} as Record<string, string>,
)

const body = new ConnectionStateUpdated({
connectionId: record.id,
invitationId: record.outOfBandId,
state: record.state,
metadata,
})

await sendWebhookEvent(config.webhookUrl + '/connection-state-updated', body, config.logger)
},
)
}
11 changes: 11 additions & 0 deletions packages/main/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { KeyDerivationMethod, LogLevel } from '@credo-ts/core'
import { ValidationPipe, VersioningType } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
import * as fs from 'fs'
import * as path from 'path'

import packageJson from '../package.json'

Expand Down Expand Up @@ -86,11 +88,20 @@ const run = async () => {
'Server',
)

const discoveryOptions = (() => {
try {
return JSON.parse(fs.readFileSync(path.resolve(process.cwd(), 'discovery.json'), 'utf-8'))
} catch (error) {
console.warn('Error reading discovery.json file:', error.message)
return undefined
}
})()
const conf: ServerConfig = {
port: Number(process.env.ADMIN_PORT || 3000),
cors: Boolean(process.env.USE_CORS || false),
logger: serverLogger,
webhookUrl: process.env.EVENTS_BASE_URL || 'http://localhost:5000',
discoveryOptions,
}

await startAdminServer(agent, conf)
Expand Down
3 changes: 3 additions & 0 deletions packages/main/src/utils/ServerConfig.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Express } from 'express'

import { FeatureQueryOptions } from '@credo-ts/core'

import { TsLogger } from './logger'

export interface ServerConfig {
Expand All @@ -8,6 +10,7 @@ export interface ServerConfig {
app?: Express
logger: TsLogger
webhookUrl?: string
discoveryOptions?: FeatureQueryOptions[]
}

export interface DidWebServerConfig extends ServerConfig {
Expand Down
2 changes: 1 addition & 1 deletion packages/main/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"outDir": "./build"
},

"include": ["src/**/*", "src/routes", "test/**/*"]
"include": ["src/**/*", "src/routes", "discovery.json","test/**/*"]
}
2 changes: 1 addition & 1 deletion packages/model/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"test": "jest"
},
"dependencies": {
"@2060.io/credo-ts-didcomm-mrtd": "^0.0.10",
"@2060.io/credo-ts-didcomm-mrtd": "^0.0.12",
"@credo-ts/core": "^0.5.11",
"class-transformer": "0.5.1",
"class-validator": "0.14.1",
Expand Down
9 changes: 8 additions & 1 deletion packages/model/src/events/ConnectionStateUpdated.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DidExchangeState } from '@credo-ts/core'
import { Expose } from 'class-transformer'
import { IsString } from 'class-validator'
import { IsObject, IsOptional, IsString } from 'class-validator'

import { Event } from './Event'
import { EventType } from './EventType'
Expand All @@ -18,6 +18,7 @@ export interface ConnectionStateUpdatedOptions {
state: ExtendedDidExchangeState
timestamp?: Date
invitationId?: string
metadata?: Record<string, string>
}

export class ConnectionStateUpdated extends Event {
Expand All @@ -29,6 +30,7 @@ export class ConnectionStateUpdated extends Event {
this.state = options.state
this.timestamp = options.timestamp ?? new Date()
this.invitationId = options.invitationId
this.metadata = options.metadata
}
}

Expand All @@ -46,4 +48,9 @@ export class ConnectionStateUpdated extends Event {
@Expose()
@IsString()
public state!: ExtendedDidExchangeState

@Expose()
@IsOptional()
@IsObject()
public metadata?: Record<string, string>
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class ConnectionsEventService {
newConnection.id = event.connectionId
newConnection.createdTs = event.timestamp
newConnection.status = event.state
newConnection.metadata = event.metadata
await this.repository.create(newConnection)

if (this.eventHandler) {
Expand Down
10 changes: 6 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@
class-validator "0.14.1"
tsyringe "^4.8.0"

"@2060.io/credo-ts-didcomm-mrtd@^0.0.10":
version "0.0.10"
resolved "https://registry.yarnpkg.com/@2060.io/credo-ts-didcomm-mrtd/-/credo-ts-didcomm-mrtd-0.0.10.tgz#43add0755c9b6404850182c1e0a2b660f754f17a"
integrity sha512-dcvsH0U00c69FQr3lcthAN11k7MIu6E1KUyO0B7wDgpmYOGINwcrBjc/5q+r8JPjAsMevwCwKjw7cP0vS9pmPw==
"@2060.io/credo-ts-didcomm-mrtd@^0.0.12":
version "0.0.12"
resolved "https://registry.yarnpkg.com/@2060.io/credo-ts-didcomm-mrtd/-/credo-ts-didcomm-mrtd-0.0.12.tgz#f0388e2ae1a3652e7b42322bc953ab8e73d8ffce"
integrity sha512-VGFG9hfKnS8LhKa1ofCMZs80tUaZVwk9feHLClhk/JqbRuJZanbAnlKpP6hk8GQYJX2b0ryW2rL3UKNTRGAMTg==
dependencies:
"@li0ard/tsemrtd" "^0.2.0"
class-transformer "0.5.1"
class-validator "0.14.1"
esbuild "^0.24.0"
mrz "^4.2.0"
reflect-metadata "^0.1.13"
rxjs "^7.2.0"
tsyringe "^4.8.0"

"@2060.io/credo-ts-didcomm-user-profile@0.0.6":
Expand Down

0 comments on commit 8bc378d

Please sign in to comment.