Skip to content

Commit fd70ada

Browse files
authored
feat: support caching for anoncreds resolving (#2550)
Signed-off-by: Timo Glastra <[email protected]>
1 parent 9b17b3f commit fd70ada

File tree

13 files changed

+803
-159
lines changed

13 files changed

+803
-159
lines changed

packages/anoncreds/src/AnonCredsApi.ts

Lines changed: 31 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import {
4747
AnonCredsIssuerServiceSymbol,
4848
} from './services'
4949
import { AnonCredsRegistryService } from './services/registry/AnonCredsRegistryService'
50-
import type { Extensible } from './services/registry/base'
50+
import type { AnonCredsResolutionOptions, Extensible } from './services/registry/base'
5151
import { dateToTimestamp, storeLinkSecret } from './utils'
5252

5353
@injectable()
@@ -126,30 +126,8 @@ export class AnonCredsApi {
126126
* Retrieve a {@link AnonCredsSchema} from the registry associated
127127
* with the {@link schemaId}
128128
*/
129-
public async getSchema(schemaId: string): Promise<GetSchemaReturn> {
130-
const failedReturnBase = {
131-
resolutionMetadata: {
132-
error: 'error',
133-
message: `Unable to resolve schema ${schemaId}`,
134-
},
135-
schemaId,
136-
schemaMetadata: {},
137-
}
138-
139-
const registry = this.findRegistryForIdentifier(schemaId)
140-
if (!registry) {
141-
failedReturnBase.resolutionMetadata.error = 'unsupportedAnonCredsMethod'
142-
failedReturnBase.resolutionMetadata.message = `Unable to resolve schema ${schemaId}: No registry found for identifier ${schemaId}`
143-
return failedReturnBase
144-
}
145-
146-
try {
147-
const result = await registry.getSchema(this.agentContext, schemaId)
148-
return result
149-
} catch (error) {
150-
failedReturnBase.resolutionMetadata.message = `Unable to resolve schema ${schemaId}: ${error.message}`
151-
return failedReturnBase
152-
}
129+
public async getSchema(schemaId: string, options: AnonCredsResolutionOptions = {}): Promise<GetSchemaReturn> {
130+
return this.anonCredsRegistryService.getSchema(this.agentContext, schemaId, options)
153131
}
154132

155133
public async registerSchema<T extends Extensible = Extensible>(
@@ -199,30 +177,11 @@ export class AnonCredsApi {
199177
* Retrieve a {@link GetCredentialDefinitionReturn} from the registry associated
200178
* with the {@link credentialDefinitionId}
201179
*/
202-
public async getCredentialDefinition(credentialDefinitionId: string): Promise<GetCredentialDefinitionReturn> {
203-
const failedReturnBase = {
204-
resolutionMetadata: {
205-
error: 'error',
206-
message: `Unable to resolve credential definition ${credentialDefinitionId}`,
207-
},
208-
credentialDefinitionId,
209-
credentialDefinitionMetadata: {},
210-
}
211-
212-
const registry = this.findRegistryForIdentifier(credentialDefinitionId)
213-
if (!registry) {
214-
failedReturnBase.resolutionMetadata.error = 'unsupportedAnonCredsMethod'
215-
failedReturnBase.resolutionMetadata.message = `Unable to resolve credential definition ${credentialDefinitionId}: No registry found for identifier ${credentialDefinitionId}`
216-
return failedReturnBase
217-
}
218-
219-
try {
220-
const result = await registry.getCredentialDefinition(this.agentContext, credentialDefinitionId)
221-
return result
222-
} catch (error) {
223-
failedReturnBase.resolutionMetadata.message = `Unable to resolve credential definition ${credentialDefinitionId}: ${error.message}`
224-
return failedReturnBase
225-
}
180+
public async getCredentialDefinition(
181+
credentialDefinitionId: string,
182+
options: AnonCredsResolutionOptions = {}
183+
): Promise<GetCredentialDefinitionReturn> {
184+
return this.anonCredsRegistryService.getCredentialDefinition(this.agentContext, credentialDefinitionId, options)
226185
}
227186

228187
public async registerCredentialDefinition<T extends Extensible>(
@@ -251,17 +210,7 @@ export class AnonCredsApi {
251210
if (isFullCredentialDefinitionInput(options.credentialDefinition)) {
252211
credentialDefinition = options.credentialDefinition
253212
} else {
254-
// If the input credential definition is not a full credential definition, we need to create one first
255-
// There's a caveat to when the input contains a full credential, that the credential definition private
256-
// and key correctness proof must already be stored in the wallet
257-
const schemaRegistry = this.findRegistryForIdentifier(options.credentialDefinition.schemaId)
258-
if (!schemaRegistry) {
259-
failedReturnBase.credentialDefinitionState.reason = `Unable to register credential definition. No registry found for schemaId ${options.credentialDefinition.schemaId}`
260-
return failedReturnBase
261-
}
262-
263-
const schemaResult = await schemaRegistry.getSchema(this.agentContext, options.credentialDefinition.schemaId)
264-
213+
const schemaResult = await this.getSchema(options.credentialDefinition.schemaId)
265214
if (!schemaResult.schema) {
266215
failedReturnBase.credentialDefinitionState.reason = `error resolving schema with id ${options.credentialDefinition.schemaId}: ${schemaResult.resolutionMetadata.error} ${schemaResult.resolutionMetadata.message}`
267216
return failedReturnBase
@@ -275,12 +224,6 @@ export class AnonCredsApi {
275224
tag: options.credentialDefinition.tag,
276225
supportRevocation: options.options.supportRevocation,
277226
schema: schemaResult.schema,
278-
},
279-
// NOTE: indy-sdk support has been removed from main repo, but keeping
280-
// this in place to allow the indy-sdk to still be used as a custom package for some time
281-
// FIXME: Indy SDK requires the schema seq no to be passed in here. This is not ideal.
282-
{
283-
indyLedgerSchemaSeqNo: schemaResult.schemaMetadata.indyLedgerSeqNo,
284227
}
285228
)
286229

@@ -328,31 +271,14 @@ export class AnonCredsApi {
328271
* with the {@link revocationRegistryDefinitionId}
329272
*/
330273
public async getRevocationRegistryDefinition(
331-
revocationRegistryDefinitionId: string
274+
revocationRegistryDefinitionId: string,
275+
options: AnonCredsResolutionOptions = {}
332276
): Promise<GetRevocationRegistryDefinitionReturn> {
333-
const failedReturnBase = {
334-
resolutionMetadata: {
335-
error: 'error',
336-
message: `Unable to resolve revocation registry ${revocationRegistryDefinitionId}`,
337-
},
277+
return this.anonCredsRegistryService.getRevocationRegistryDefinition(
278+
this.agentContext,
338279
revocationRegistryDefinitionId,
339-
revocationRegistryDefinitionMetadata: {},
340-
}
341-
342-
const registry = this.findRegistryForIdentifier(revocationRegistryDefinitionId)
343-
if (!registry) {
344-
failedReturnBase.resolutionMetadata.error = 'unsupportedAnonCredsMethod'
345-
failedReturnBase.resolutionMetadata.message = `Unable to resolve revocation registry ${revocationRegistryDefinitionId}: No registry found for identifier ${revocationRegistryDefinitionId}`
346-
return failedReturnBase
347-
}
348-
349-
try {
350-
const result = await registry.getRevocationRegistryDefinition(this.agentContext, revocationRegistryDefinitionId)
351-
return result
352-
} catch (error) {
353-
failedReturnBase.resolutionMetadata.message = `Unable to resolve revocation registry ${revocationRegistryDefinitionId}: ${error.message}`
354-
return failedReturnBase
355-
}
280+
options
281+
)
356282
}
357283

358284
public async registerRevocationRegistryDefinition<T extends Extensible = Extensible>(
@@ -379,7 +305,7 @@ export class AnonCredsApi {
379305
return failedReturnBase
380306
}
381307

382-
const { credentialDefinition } = await registry.getCredentialDefinition(this.agentContext, credentialDefinitionId)
308+
const { credentialDefinition } = await this.getCredentialDefinition(credentialDefinitionId)
383309

384310
if (!credentialDefinition) {
385311
failedReturnBase.revocationRegistryDefinitionState.reason = `Unable to register revocation registry definition. No credential definition found for id ${credentialDefinitionId}`
@@ -436,34 +362,15 @@ export class AnonCredsApi {
436362
*/
437363
public async getRevocationStatusList(
438364
revocationRegistryDefinitionId: string,
439-
timestamp: number
365+
timestamp: number,
366+
options: Omit<AnonCredsResolutionOptions, 'useLocalRecord'> = {}
440367
): Promise<GetRevocationStatusListReturn> {
441-
const failedReturnBase = {
442-
resolutionMetadata: {
443-
error: 'error',
444-
message: `Unable to resolve revocation status list for revocation registry ${revocationRegistryDefinitionId}`,
445-
},
446-
revocationStatusListMetadata: {},
447-
}
448-
449-
const registry = this.findRegistryForIdentifier(revocationRegistryDefinitionId)
450-
if (!registry) {
451-
failedReturnBase.resolutionMetadata.error = 'unsupportedAnonCredsMethod'
452-
failedReturnBase.resolutionMetadata.message = `Unable to resolve revocation status list for revocation registry ${revocationRegistryDefinitionId}: No registry found for identifier ${revocationRegistryDefinitionId}`
453-
return failedReturnBase
454-
}
455-
456-
try {
457-
const result = await registry.getRevocationStatusList(
458-
this.agentContext,
459-
revocationRegistryDefinitionId,
460-
timestamp
461-
)
462-
return result
463-
} catch (error) {
464-
failedReturnBase.resolutionMetadata.message = `Unable to resolve revocation status list for revocation registry ${revocationRegistryDefinitionId}: ${error.message}`
465-
return failedReturnBase
466-
}
368+
return this.anonCredsRegistryService.getRevocationStatusList(
369+
this.agentContext,
370+
revocationRegistryDefinitionId,
371+
timestamp,
372+
options
373+
)
467374
}
468375

469376
public async registerRevocationStatusList<T extends Extensible = Extensible>(
@@ -486,10 +393,7 @@ export class AnonCredsApi {
486393
return failedReturnBase
487394
}
488395

489-
const { revocationRegistryDefinition } = await registry.getRevocationRegistryDefinition(
490-
this.agentContext,
491-
revocationRegistryDefinitionId
492-
)
396+
const { revocationRegistryDefinition } = await this.getRevocationRegistryDefinition(revocationRegistryDefinitionId)
493397

494398
if (!revocationRegistryDefinition) {
495399
failedReturnBase.revocationStatusListState.reason = `Unable to register revocation status list. No revocation registry definition found for ${revocationRegistryDefinitionId}`
@@ -547,10 +451,7 @@ export class AnonCredsApi {
547451
return failedReturnBase
548452
}
549453

550-
const { revocationRegistryDefinition } = await registry.getRevocationRegistryDefinition(
551-
this.agentContext,
552-
revocationRegistryDefinitionId
553-
)
454+
const { revocationRegistryDefinition } = await this.getRevocationRegistryDefinition(revocationRegistryDefinitionId)
554455

555456
if (!revocationRegistryDefinition) {
556457
failedReturnBase.revocationStatusListState.reason = `Unable to update revocation status list. No revocation registry definition found for ${revocationRegistryDefinitionId}`
@@ -559,7 +460,11 @@ export class AnonCredsApi {
559460

560461
const { revocationStatusList: previousRevocationStatusList } = await this.getRevocationStatusList(
561462
revocationRegistryDefinitionId,
562-
dateToTimestamp(new Date())
463+
dateToTimestamp(new Date()),
464+
// We want the latest state here.
465+
{
466+
useCache: false,
467+
}
563468
)
564469

565470
if (!previousRevocationStatusList) {

packages/anoncreds/src/services/registry/AnonCredsRegistry.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,28 @@ import type { GetSchemaReturn, RegisterSchemaOptions, RegisterSchemaReturn } fro
2121
*/
2222
export interface AnonCredsRegistry {
2323
/**
24-
* A name to identify the registry. This will be stored as part of the reigstered anoncreds objects to allow querying
25-
* for created objects using a specific registry. Multilpe implementations can use the same name, but they should in that
24+
* A name to identify the registry. This will be stored as part of the registered anoncreds objects to allow querying
25+
* for created objects using a specific registry. Multiple implementations can use the same name, but they should in that
2626
* case also reference objects on the same networks.
2727
*/
2828
methodName: string
2929

3030
supportedIdentifier: RegExp
3131

32+
/**
33+
* Whether this registry allows caching of resolved objects (as well as caching
34+
* just created objects).
35+
*/
36+
readonly allowsCaching?: boolean
37+
38+
/**
39+
* Whether the resolver allows using a local created object from
40+
* a record to resolve the object.
41+
*
42+
* @default false
43+
*/
44+
readonly allowsLocalRecord?: boolean
45+
3246
getSchema(agentContext: AgentContext, schemaId: string): Promise<GetSchemaReturn>
3347
registerSchema(agentContext: AgentContext, options: RegisterSchemaOptions): Promise<RegisterSchemaReturn>
3448

0 commit comments

Comments
 (0)