Newer
Older
import type { AppAgent } from '../agent.service.js';
import type {
ConnectionRecord,
ConnectionStateChangedEvent,
EventDidcommConnectionsBlock,
EventDidcommConnectionsBlockInput,
EventDidcommConnectionsCreateInvitationInput,
EventDidcommConnectionsCreateWithSelf,
EventDidcommConnectionsCreateWithSelfInput,
EventDidcommConnectionsGetAllInput,
EventDidcommConnectionsGetById,
EventDidcommConnectionsGetByIdInput,
EventDidcommConnectionsReceiveInvitationFromUrlInput,
} from '@ocm/shared';
import {
ConnectionEventTypes,
ConnectionRepository,
DidExchangeState,
} from '@credo-ts/core';
import { isDid } from '@credo-ts/core/build/utils/did.js';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { MetadataTokens } from '../../common/constants.js';
import { AgentService } from '../agent.service.js';
import { WithTenantService } from '../withTenantService.js';
export class ConnectionsService {
public constructor(
agentService: AgentService,
private withTenantService: WithTenantService,
private configService: ConfigService,
public async getAll({
tenantId,
}: EventDidcommConnectionsGetAllInput): Promise<Array<ConnectionRecord>> {
return this.withTenantService.invoke(tenantId, (t) =>
t.connections.getAll(),
);
public async getById({
tenantId,
id,
}: EventDidcommConnectionsGetByIdInput): Promise<
EventDidcommConnectionsGetById['data']
> {
return this.withTenantService.invoke(tenantId, (t) =>
t.connections.findById(id),
);
public async blockByIdOrDid({
tenantId,
idOrDid,
}: EventDidcommConnectionsBlockInput): Promise<
EventDidcommConnectionsBlock['data']
> {
return this.withTenantService.invoke(tenantId, async (t) => {
if (isDid(idOrDid)) {
const records = await t.connections.findAllByQuery({
theirDid: idOrDid,
});
if (records.length === 0) {
return null;
}
if (records.length > 1) {
throw new Error(
'Found multiple records with the same DID. This should not be possible',
);
}
await t.connections.deleteById(records[0].id);
const record = await t.connections.findById(idOrDid);
if (!record) return null;
await t.connections.deleteById(record.id);
return record;
});
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
public async createInvitation({
tenantId,
}: EventDidcommConnectionsCreateInvitationInput): Promise<{
invitationUrl: string;
}> {
const host = this.configService.get<string>('agent.host');
if (!host) {
throw new Error(
'Could not get the `agentHost` from the config. This is required to create an invitation',
);
}
return this.withTenantService.invoke(tenantId, async (t) => {
const { outOfBandInvitation } = await t.oob.createInvitation();
return {
invitationUrl: outOfBandInvitation.toUrl({
domain: host,
}),
};
});
}
public async receiveInvitationFromUrl({
tenantId,
invitationUrl,
}: EventDidcommConnectionsReceiveInvitationFromUrlInput): Promise<ConnectionRecord> {
return this.withTenantService.invoke(tenantId, async (t) => {
const { connectionRecord } =
await t.oob.receiveInvitationFromUrl(invitationUrl);
if (!connectionRecord) {
throw new Error(
'Invitation did not establish a connection. Is it a connection invitation?',
);
}
return connectionRecord;
});
}
public async createConnectionWithSelf({
tenantId,
}: EventDidcommConnectionsCreateWithSelfInput): Promise<
EventDidcommConnectionsCreateWithSelf['data']
> {
return this.withTenantService.invoke(tenantId, async (t) => {
const outOfBandRecord = await t.oob.createInvitation();
const invitation = outOfBandRecord.outOfBandInvitation;
const { connectionRecord } = await t.oob.receiveInvitation(invitation);
if (connectionRecord) {
connectionRecord.metadata.set(MetadataTokens.CONNECTION_METADATA_KEY, {
trusted: true,
withSelf: true,
});
const connRepo = t.dependencyManager.resolve(ConnectionRepository);
await connRepo.update(t.context, connectionRecord);
}
return new Promise((resolve) =>
this.agent.events.on<ConnectionStateChangedEvent>(
ConnectionEventTypes.ConnectionStateChanged,
async ({ payload: { connectionRecord } }) => {
if (connectionRecord.state !== DidExchangeState.Completed) return;
connectionRecord.metadata.set(
Berend Sliedrecht
committed
MetadataTokens.CONNECTION_METADATA_KEY,
{
trusted: true,
},
);
const connRepo = t.dependencyManager.resolve(ConnectionRepository);
await connRepo.update(t.context, connectionRecord);
resolve(connectionRecord);
},
),
);
});