Skip to content

Commit

Permalink
feat(anoncreds): add anoncreds registry service (#1204)
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra authored Jan 12, 2023
1 parent 8a04d1b commit 86647e7
Show file tree
Hide file tree
Showing 15 changed files with 254 additions and 40 deletions.
23 changes: 23 additions & 0 deletions packages/anoncreds/src/AnonCredsModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { AnonCredsModuleConfigOptions } from './AnonCredsModuleConfig'
import type { DependencyManager, Module } from '@aries-framework/core'

import { AnonCredsModuleConfig } from './AnonCredsModuleConfig'
import { AnonCredsRegistryService } from './services/registry/AnonCredsRegistryService'

/**
* @public
*/
export class AnonCredsModule implements Module {
public readonly config: AnonCredsModuleConfig

public constructor(config: AnonCredsModuleConfigOptions) {
this.config = new AnonCredsModuleConfig(config)
}

public register(dependencyManager: DependencyManager) {
// Config
dependencyManager.registerInstance(AnonCredsModuleConfig, this.config)

dependencyManager.registerSingleton(AnonCredsRegistryService)
}
}
28 changes: 28 additions & 0 deletions packages/anoncreds/src/AnonCredsModuleConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { AnonCredsRegistry } from './services'

/**
* @public
* AnonCredsModuleConfigOptions defines the interface for the options of the AnonCredsModuleConfig class.
*/
export interface AnonCredsModuleConfigOptions {
/**
* A list of AnonCreds registries to make available to the AnonCreds module.
*/
registries: [AnonCredsRegistry, ...AnonCredsRegistry[]]
}

/**
* @public
*/
export class AnonCredsModuleConfig {
private options: AnonCredsModuleConfigOptions

public constructor(options: AnonCredsModuleConfigOptions) {
this.options = options
}

/** See {@link AnonCredsModuleConfigOptions.registries} */
public get registries() {
return this.options.registries
}
}
28 changes: 28 additions & 0 deletions packages/anoncreds/src/__tests__/AnonCredsModule.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { AnonCredsRegistry } from '../services'
import type { DependencyManager } from '@aries-framework/core'

import { AnonCredsModule } from '../AnonCredsModule'
import { AnonCredsModuleConfig } from '../AnonCredsModuleConfig'
import { AnonCredsRegistryService } from '../services/registry/AnonCredsRegistryService'

const dependencyManager = {
registerInstance: jest.fn(),
registerSingleton: jest.fn(),
} as unknown as DependencyManager

const registry = {} as AnonCredsRegistry

describe('AnonCredsModule', () => {
test('registers dependencies on the dependency manager', () => {
const anonCredsModule = new AnonCredsModule({
registries: [registry],
})
anonCredsModule.register(dependencyManager)

expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(1)
expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(AnonCredsRegistryService)

expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1)
expect(dependencyManager.registerInstance).toHaveBeenCalledWith(AnonCredsModuleConfig, anonCredsModule.config)
})
})
15 changes: 15 additions & 0 deletions packages/anoncreds/src/__tests__/AnonCredsModuleConfig.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { AnonCredsRegistry } from '../services'

import { AnonCredsModuleConfig } from '../AnonCredsModuleConfig'

describe('AnonCredsModuleConfig', () => {
test('sets values', () => {
const registry = {} as AnonCredsRegistry

const config = new AnonCredsModuleConfig({
registries: [registry],
})

expect(config.registries).toEqual([registry])
})
})
7 changes: 7 additions & 0 deletions packages/anoncreds/src/error/AnonCredsError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { AriesFrameworkError } from '@aries-framework/core'

export class AnonCredsError extends AriesFrameworkError {
public constructor(message: string, { cause }: { cause?: Error } = {}) {
super(message, { cause })
}
}
1 change: 1 addition & 0 deletions packages/anoncreds/src/error/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AnonCredsError'
3 changes: 3 additions & 0 deletions packages/anoncreds/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from './models'
export * from './services'
export * from './error'
export { AnonCredsModule } from './AnonCredsModule'
export { AnonCredsModuleConfig, AnonCredsModuleConfigOptions } from './AnonCredsModuleConfig'
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import type { GetRevocationRegistryDefinitionReturn } from './RevocationRegistry
import type { GetSchemaReturn, RegisterSchemaOptions, RegisterSchemaReturn } from './SchemaOptions'
import type { AgentContext } from '@aries-framework/core'

// This service can be registered multiple times in a single AFJ instance.
/**
* @public
*/
export interface AnonCredsRegistry {
supportedIdentifier: RegExp

getSchema(agentContext: AgentContext, schemaId: string): Promise<GetSchemaReturn>
registerSchema(agentContext: AgentContext, options: RegisterSchemaOptions): Promise<RegisterSchemaReturn>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { AnonCredsRegistry } from '.'
import type { AgentContext } from '@aries-framework/core'

import { injectable } from '@aries-framework/core'

import { AnonCredsModuleConfig } from '../../AnonCredsModuleConfig'
import { AnonCredsError } from '../../error'

/**
* @internal
* The AnonCreds registry service manages multiple {@link AnonCredsRegistry} instances
* and returns the correct registry based on a given identifier
*/
@injectable()
export class AnonCredsRegistryService {
public async getRegistryForIdentifier(agentContext: AgentContext, identifier: string): Promise<AnonCredsRegistry> {
const registries = agentContext.dependencyManager.resolve(AnonCredsModuleConfig).registries

// TODO: should we check if multiple are registered?
const registry = registries.find((registry) => registry.supportedIdentifier.test(identifier))

if (!registry) {
throw new AnonCredsError(`No AnonCredsRegistry registered for identifier '${registry}'`)
}

return registry
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { AnonCredsRegistry } from '../AnonCredsRegistry'

import { getAgentContext } from '../../../../../core/tests/helpers'
import { AnonCredsModuleConfig } from '../../../AnonCredsModuleConfig'
import { AnonCredsError } from '../../../error'
import { AnonCredsRegistryService } from '../AnonCredsRegistryService'

const registryOne = {
supportedIdentifier: /a/,
} as AnonCredsRegistry

const registryTwo = {
supportedIdentifier: /b/,
} as AnonCredsRegistry

const agentContext = getAgentContext({
registerInstances: [
[
AnonCredsModuleConfig,
new AnonCredsModuleConfig({
registries: [registryOne, registryTwo],
}),
],
],
})

const anonCredsRegistryService = new AnonCredsRegistryService()

describe('AnonCredsRegistryService', () => {
test('returns the registry for an identifier based on the supportedMethods regex', async () => {
await expect(anonCredsRegistryService.getRegistryForIdentifier(agentContext, 'a')).resolves.toEqual(registryOne)
await expect(anonCredsRegistryService.getRegistryForIdentifier(agentContext, 'b')).resolves.toEqual(registryTwo)
})

test('throws AnonCredsError if no registry is found for the given identifier', async () => {
await expect(anonCredsRegistryService.getRegistryForIdentifier(agentContext, 'c')).rejects.toThrow(AnonCredsError)
})
})
2 changes: 1 addition & 1 deletion packages/indy-sdk/src/IndySdkModuleConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class IndySdkModuleConfig {
this.options = options
}

/** See {@link IndySdkModuleConfigOptions.resolvers} */
/** See {@link IndySdkModuleConfigOptions.indySdk} */
public get indySdk() {
return this.options.indySdk
}
Expand Down
Loading

0 comments on commit 86647e7

Please sign in to comment.