From c7a728baae4be62834129526377877691bf0b1df Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Sun, 5 Feb 2023 19:07:51 +0100 Subject: [PATCH 01/11] feat(indy-vdr): add anoncreds package Signed-off-by: Victor Anene --- packages/indy-vdr/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/indy-vdr/package.json b/packages/indy-vdr/package.json index 32c8689d5d..eaf4518867 100644 --- a/packages/indy-vdr/package.json +++ b/packages/indy-vdr/package.json @@ -26,6 +26,7 @@ }, "dependencies": { "@aries-framework/core": "0.3.3", + "@aries-framework/anoncreds": "0.3.3", "indy-vdr-test-shared": "^0.1.3" }, "devDependencies": { From 64fd3508f23d58880186b4752d9a3ce49df2dc0c Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Mon, 6 Feb 2023 00:47:24 +0100 Subject: [PATCH 02/11] feat(indy-vdr): add IndyVdrAnoncredsRegistry work funded by the Government of Ontario Signed-off-by: Victor Anene --- .../src/anoncreds/indyVdrAnoncredsRegistry.ts | 375 ++++++++++++++++++ .../src/anoncreds/utils/identifiers.ts | 36 ++ 2 files changed, 411 insertions(+) create mode 100644 packages/indy-vdr/src/anoncreds/utils/identifiers.ts diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts index e69de29bb2..8375c6b31e 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts @@ -0,0 +1,375 @@ +import type { + AnonCredsRegistry, + GetCredentialDefinitionReturn, + GetSchemaReturn, + RegisterSchemaOptions, + RegisterCredentialDefinitionOptions, + RegisterSchemaReturn, + RegisterCredentialDefinitionReturn, + GetRevocationListReturn, + GetRevocationRegistryDefinitionReturn + } from '@aries-framework/anoncreds' + import { AgentContext, DidsApi, getKeyDidMappingByVerificationMethod, AriesFrameworkError } from '@aries-framework/core' + import { CredentialDefinitionRequest, GetSchemaRequest, GetCredentialDefinitionRequest, SchemaRequest } from '@hyperledger/indy-vdr-shared' + + import { IndyVdrPoolService } from '../pool' + import { didFromSchemaId, didFromCredentialDefinitionId, getLegacySchemaId, getLegacyCredentialDefinitionId, indyVdrAnonCredsRegistryIdentifierRegex } from './utils/identifiers' + + export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { + public readonly supportedIdentifier = indyVdrAnonCredsRegistryIdentifierRegex + + public async getSchema(agentContext: AgentContext, schemaId: string): Promise { + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const did = didFromSchemaId(schemaId) + + const pool = await indyVdrPoolService.getPoolForDid(agentContext, did) + + agentContext.config.logger.debug(`Getting schema '${schemaId}' from ledger '${pool.indyNamespace}'`) + const request = new GetSchemaRequest({ submitterDid: did, schemaId }) + + agentContext.config.logger.trace( + `Submitting get schema request for schema '${schemaId}' to ledger '${pool.indyNamespace}'` + ) + const response = await pool.submitReadRequest(request) + + agentContext.config.logger.trace(`Got un-parsed schema '${schemaId}' from ledger '${pool.indyNamespace}'`, { + response, + }) + + const issuerId = didFromSchemaId(schemaId) + + if ('attr_names' in response.result.data) { + return { + schema: { + attrNames: response.result.data.attr_names, + name: response.result.data.name, + version: response.result.data.version, + issuerId, + }, + schemaId: schemaId, + resolutionMetadata: {}, + schemaMetadata: { + didIndyNamespace: pool.indyNamespace, + // NOTE: the seqNo is required by the indy-sdk even though not present in AnonCreds v1. + // For this reason we return it in the metadata. + indyLedgerSeqNo: response.result.seqNo, + }, + } + + } + + agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`) + + return { + schemaId, + resolutionMetadata: { + error: 'notFound', + message: `unable to find schema with id ${schemaId}`, + }, + schemaMetadata: {} + } + + } catch (error) { + agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`, { + error, + schemaId, + }) + + return { + schemaId, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve credential definition: ${error.message}`, + }, + schemaMetadata: {}, + } + } + } + + public async registerSchema( + agentContext: AgentContext, + options: IndyVdrRegisterSchemaOptions + ): Promise { + if (!options.options.didIndyNamespace) { + return { + schemaMetadata: {}, + registrationMetadata: {}, + schemaState: { + reason: 'no didIndyNamespace defined in the options. didIndyNamespace is required when using the Indy VDR', + schema: options.schema, + state: 'failed', + }, + } + } + + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const schemaRequest = new SchemaRequest({ + submitterDid: options.schema.issuerId, + schema: { + id: getLegacySchemaId(options.schema.issuerId, options.schema.name, options.schema.version), + name: options.schema.name, + ver: '1.0', + version: options.schema.version, + attrNames: options.schema.attrNames, + }, + }) + + const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace); + + // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did + // from the ledger to know which key is associated with the did + // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did + // from the ledger to know which key is associated with the did + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didResult = await didsApi.resolve(`did:sov:${options.schema.issuerId}`) + + if (!didResult.didDocument) throw new AriesFrameworkError('Unable to resolve did') + + const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') + const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) + const key = getKeyFromVerificationMethod(verificationMethod) + + const response = await pool.submitWriteRequest(agentContext, schemaRequest, key) + + return { + schemaState: { + state: 'finished', + schema: { + attrNames: options.schema.attrNames, + issuerId: options.schema.issuerId, + name: options.schema.name, + version: options.schema.version, + }, + schemaId: getLegacySchemaId(options.schema.issuerId, options.schema.name, options.schema.version), + }, + registrationMetadata: {}, + schemaMetadata: { + // NOTE: the seqNo is required by the indy-sdk even though not present in AnonCreds v1. + // For this reason we return it in the metadata. + indyLedgerSeqNo: response.result.txnMetadata.seqNo, + didIndyNamespace: pool.indyNamespace, + }, + + } + + + } catch (error) { + agentContext.config.logger.error(`Error registering schema for did '${options.schema.issuerId}'`, { + error, + did: options.schema.issuerId, + schema: options.schema, + }) + + return { + schemaMetadata: {}, + registrationMetadata: {}, + schemaState: { + state: 'failed', + schema: options.schema, + reason: `unknownError: ${error.message}`, + }, + } + } + } + + public async getCredentialDefinition( + agentContext: AgentContext, + credentialDefinitionId: string + ): Promise { + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const did = didFromCredentialDefinitionId(credentialDefinitionId) + + const pool = await indyVdrPoolService.getPoolForDid(agentContext, did) + + agentContext.config.logger.debug( + `Getting credential definition '${credentialDefinitionId}' from ledger '${pool.indyNamespace}'` + ) + + const request = new GetCredentialDefinitionRequest({ + submitterDid: did, + credentialDefinitionId + }); + + agentContext.config.logger.trace( + `Submitting get credential definition request for credential definition '${credentialDefinitionId}' to ledger '${pool.indyNamespace}'` + ) + + const response = await pool.submitReadRequest(request) + + if (response.result.data) { + return { + credentialDefinitionId: credentialDefinitionId, + credentialDefinition: { + issuerId: didFromCredentialDefinitionId(credentialDefinitionId), + schemaId: response.result.ref.toString(), + tag: response.result.tag, + type: 'CL', + value: response.result.data, + }, + credentialDefinitionMetadata: { + didIndyNamespace: pool.indyNamespace, + }, + resolutionMetadata: {}, + } + } + + agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`) + + return { + credentialDefinitionId, + credentialDefinitionMetadata: {}, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve credential definition with id ${credentialDefinitionId}`, + }, + } + + } catch (error) { + agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`, { + error, + credentialDefinitionId, + }) + + return { + credentialDefinitionId, + credentialDefinitionMetadata: {}, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve credential definition: ${error.message}`, + }, + } + } + } + + public async registerCredentialDefinition(agentContext: AgentContext, options: IndyVdrRegisterCredentialDefinitionOptions): Promise { + // Make sure didIndyNamespace is passed + if (!options.options.didIndyNamespace) { + return { + credentialDefinitionMetadata: {}, + registrationMetadata: {}, + credentialDefinitionState: { + reason: 'no didIndyNamespace defined in the options. didIndyNamespace is required when using the Indy SDK', + credentialDefinition: options.credentialDefinition, + state: 'failed', + }, + } + } + + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService); + + //TODO: get schema SeqNo + const credentialDefinitionId = getLegacyCredentialDefinitionId(options.options.didIndyNamespace, options.credentialDefinition., options.credentialDefinition.tag), + + const credentialDefinitionRequest = new CredentialDefinitionRequest({ + submitterDid: options.credentialDefinition.issuerId, + credentialDefinition: { + ver: '1.0', + id: credentialDefinitionId, + schemaId: options.credentialDefinition.schemaId, + type: 'CL', + tag: options.credentialDefinition.tag, + value: { + primary: options.credentialDefinition.value, + + }, + }, + }) + + const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace); + + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didResult = await didsApi.resolve(`did:sov:${options.credentialDefinition.issuerId}`) + + if (!didResult.didDocument) throw new AriesFrameworkError('Unable to resolve did') + + const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') + const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) + const key = getKeyFromVerificationMethod(verificationMethod) + + const response = await pool.submitWriteRequest(agentContext, credentialDefinitionRequest, key); + + agentContext.config.logger.debug( + `Registered credential definition '${credentialDefinitionId}' on ledger '${pool.indyNamespace}'`, + { + response, + credentialDefinition: options.credentialDefinition, + } + ) + + return { + credentialDefinitionMetadata: { + didIndyNamespace: pool.indyNamespace, + }, + credentialDefinitionState: { + credentialDefinition: options.credentialDefinition, + credentialDefinitionId, + state: 'finished', + }, + registrationMetadata: {}, + } + } catch (error) { + agentContext.config.logger.error( + `Error registering credential definition for schema '${options.credentialDefinition.schemaId}'`, + { + error, + did: options.credentialDefinition.issuerId, + credentialDefinition: options.credentialDefinition, + } + ) + + return { + credentialDefinitionMetadata: {}, + registrationMetadata: {}, + credentialDefinitionState: { + credentialDefinition: options.credentialDefinition, + state: 'failed', + reason:`unknownError: ${error.message}` + } + } + } + } + + public async getRevocationList(agentContext: AgentContext, revocationRegistryId: string, timestamp: number): Promise { + return { + resolutionMetadata: { + error: 'Not Implemented', + message: `Revocation list not yet implemented `, + }, + revocationListMetadata: {}, + } + } + + public async getRevocationRegistryDefinition( + agentContext: AgentContext, + revocationRegistryDefinitionId: string + ): Promise { + return { + resolutionMetadata: { + error: 'Not Implemented', + message: `Revocation registry definition not yet implemented`, + }, + revocationRegistryDefinitionId, + revocationRegistryDefinitionMetadata: {}, + } + } + } + + export interface IndyVdrRegisterSchemaOptions extends RegisterSchemaOptions { + options: { + didIndyNamespace: string + } + } + + export interface IndyVdrRegisterCredentialDefinitionOptions extends RegisterCredentialDefinitionOptions { + options: { + didIndyNamespace: string + } + } + \ No newline at end of file diff --git a/packages/indy-vdr/src/anoncreds/utils/identifiers.ts b/packages/indy-vdr/src/anoncreds/utils/identifiers.ts new file mode 100644 index 0000000000..ce240883e1 --- /dev/null +++ b/packages/indy-vdr/src/anoncreds/utils/identifiers.ts @@ -0,0 +1,36 @@ +export const legacyIndyVdrIssuerIdRegex = /^[a-zA-Z0-9]{21,22}$/ +export const legacyIndyVdrSchemaIdRegex = /^[a-zA-Z0-9]{21,22}:2:.+:[0-9.]+$/ +export const legacyIndyVdrCredentialDefinitionIdRegex = + /^[a-zA-Z0-9]{21,22}:3:CL:(([1-9][0-9]*)|([a-zA-Z0-9]{21,22}:2:.+:[0-9.]+)):(.+)?$/ +export const legacyIndyVdrRevocationRegistryIdRegex = + /^[a-zA-Z0-9]{21,22}:4:[a-zA-Z0-9]{21,22}:3:CL:(([1-9][0-9]*)|([a-zA-Z0-9]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)/ + +export const indyVdrAnonCredsRegistryIdentifierRegex = new RegExp( + `${legacyIndyVdrIssuerIdRegex.source}|${legacyIndyVdrSchemaIdRegex.source}|${legacyIndyVdrCredentialDefinitionIdRegex.source}|${legacyIndyVdrRevocationRegistryIdRegex.source}` + ) + +export function getLegacySchemaId(unqualifiedDid: string, name: string, version: string) { + return `${unqualifiedDid}:2:${name}:${version}` + } + + export function getLegacyCredentialDefinitionId(unqualifiedDid: string, seqNo: number, tag: string) { + return `${unqualifiedDid}:3:CL:${seqNo}:${tag}` + } + + /** + * Extract did from schema id + */ +export function didFromSchemaId(schemaId: string) { + const [did] = schemaId.split(':') + + return did + } + + /** + * Extract did from credential definition id + */ + export function didFromCredentialDefinitionId(credentialDefinitionId: string) { + const [did] = credentialDefinitionId.split(':') + + return did + } \ No newline at end of file From 1fed49e87a5aa97bb0f1e07e25524e56899ebf78 Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Tue, 7 Feb 2023 00:56:45 +0100 Subject: [PATCH 03/11] test(indy-vdr): test for indyVdrAnoncredsRegistry identifiers work funded by the Government of Ontario Signed-off-by: Victor Anene --- .../utils/_tests_/identifier.test.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts diff --git a/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts b/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts new file mode 100644 index 0000000000..e3da8f05a1 --- /dev/null +++ b/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts @@ -0,0 +1,49 @@ +import {getLegacySchemaId, getLegacyCredentialDefinitionId, didFromSchemaId, didFromCredentialDefinitionId, indyVdrAnonCredsRegistryIdentifierRegex} from '../identifiers' + +describe('identifiers', () => { + it('matches against a legacy indy did, schema id, credential definition id and revocation registry id', () => { + const did = '7Tqg6BwSSWapxgUDm9KKgg' + const schemaId = 'BQ42WeE24jFHeyGg8x9XAz:2:Medical Bill:1.0' + const credentialDefinitionId = 'N7baRMcyvPwWc8v85CtZ6e:3:CL:100669:SCH Employee ID' + const revocationRegistryId = + 'N7baRMcyvPwWc8v85CtZ6e:4:N7baRMcyvPwWc8v85CtZ6e:3:CL:100669:SCH Employee ID:CL_ACCUM:1-1024' + + const anotherId = 'some:id' + + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(did)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(schemaId)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(credentialDefinitionId)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(revocationRegistryId)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(anotherId)).toEqual(false) + }) + + it('getLegacySchemaId should return a valid schema Id', () => { + const did = '29347' + const name = 'starlinks' + const version = '321' + + expect(getLegacySchemaId(did, name, version)).toEqual(`29347:2:starlinks:321`) + }) + + it ('getLegacyCredentialDefinition should return a valid Credential Id', () => { + + const did = '15565' + const seqNo = 323 + const tag = 'indyTag' + expect(getLegacyCredentialDefinitionId(did, seqNo, tag)).toEqual('15565:3:CL:323:indyTag') + }) + + it ('didFromSchemaId should return the valid did from the schema', () => { + const schemaId = '29347:2:starlinks:321' + + expect(didFromSchemaId(schemaId)).toEqual('29347') + }) + + it ('didFromCredentialId should return the valid did from the schema', () => { + const credentialDefinitionId = '15565:3:CL:323:indyTag' + + expect(didFromCredentialDefinitionId(credentialDefinitionId)).toEqual('15565') + }) + + +}) \ No newline at end of file From 80f87ca3478f6e3b1fa72428c28c393f4438e321 Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Tue, 7 Feb 2023 16:19:54 +0100 Subject: [PATCH 04/11] fix: linter error Signed-off-by: Victor Anene --- packages/indy-vdr/package.json | 1 - .../src/anoncreds/indyVdrAnoncredsRegistry.ts | 650 ++++++++++-------- .../utils/_tests_/identifier.test.ts | 97 +-- .../src/anoncreds/utils/identifiers.ts | 44 +- 4 files changed, 424 insertions(+), 368 deletions(-) diff --git a/packages/indy-vdr/package.json b/packages/indy-vdr/package.json index 2fefb61be1..e12d0116de 100644 --- a/packages/indy-vdr/package.json +++ b/packages/indy-vdr/package.json @@ -26,7 +26,6 @@ }, "dependencies": { "@aries-framework/core": "0.3.3", - "@aries-framework/anoncreds": "0.3.3", "@hyperledger/indy-vdr-shared": "^0.1.0-dev.4" }, "devDependencies": { diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts index 8375c6b31e..2f5c5dbf3d 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts @@ -1,140 +1,161 @@ import type { - AnonCredsRegistry, - GetCredentialDefinitionReturn, - GetSchemaReturn, - RegisterSchemaOptions, - RegisterCredentialDefinitionOptions, - RegisterSchemaReturn, - RegisterCredentialDefinitionReturn, - GetRevocationListReturn, - GetRevocationRegistryDefinitionReturn - } from '@aries-framework/anoncreds' - import { AgentContext, DidsApi, getKeyDidMappingByVerificationMethod, AriesFrameworkError } from '@aries-framework/core' - import { CredentialDefinitionRequest, GetSchemaRequest, GetCredentialDefinitionRequest, SchemaRequest } from '@hyperledger/indy-vdr-shared' - - import { IndyVdrPoolService } from '../pool' - import { didFromSchemaId, didFromCredentialDefinitionId, getLegacySchemaId, getLegacyCredentialDefinitionId, indyVdrAnonCredsRegistryIdentifierRegex } from './utils/identifiers' - - export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { - public readonly supportedIdentifier = indyVdrAnonCredsRegistryIdentifierRegex - - public async getSchema(agentContext: AgentContext, schemaId: string): Promise { - try { - const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) - - const did = didFromSchemaId(schemaId) - - const pool = await indyVdrPoolService.getPoolForDid(agentContext, did) - - agentContext.config.logger.debug(`Getting schema '${schemaId}' from ledger '${pool.indyNamespace}'`) - const request = new GetSchemaRequest({ submitterDid: did, schemaId }) - - agentContext.config.logger.trace( - `Submitting get schema request for schema '${schemaId}' to ledger '${pool.indyNamespace}'` - ) - const response = await pool.submitReadRequest(request) - - agentContext.config.logger.trace(`Got un-parsed schema '${schemaId}' from ledger '${pool.indyNamespace}'`, { - response, - }) - - const issuerId = didFromSchemaId(schemaId) - - if ('attr_names' in response.result.data) { - return { - schema: { - attrNames: response.result.data.attr_names, - name: response.result.data.name, - version: response.result.data.version, - issuerId, - }, - schemaId: schemaId, - resolutionMetadata: {}, - schemaMetadata: { - didIndyNamespace: pool.indyNamespace, - // NOTE: the seqNo is required by the indy-sdk even though not present in AnonCreds v1. - // For this reason we return it in the metadata. - indyLedgerSeqNo: response.result.seqNo, - }, - } - - } - - agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`) - + AnonCredsRegistry, + GetCredentialDefinitionReturn, + GetSchemaReturn, + RegisterSchemaOptions, + RegisterCredentialDefinitionOptions, + RegisterSchemaReturn, + RegisterCredentialDefinitionReturn, + GetRevocationListReturn, + GetRevocationRegistryDefinitionReturn, +} from '@aries-framework/anoncreds' +import type { AgentContext } from '@aries-framework/core' + +import { DidsApi, getKeyDidMappingByVerificationMethod } from '@aries-framework/core' +import { + CredentialDefinitionRequest, + GetSchemaRequest, + GetCredentialDefinitionRequest, + SchemaRequest, +} from '@hyperledger/indy-vdr-shared' + +import { IndyVdrPoolService } from '../pool' + +import { + didFromSchemaId, + didFromCredentialDefinitionId, + getLegacySchemaId, + getLegacyCredentialDefinitionId, + indyVdrAnonCredsRegistryIdentifierRegex, +} from './utils/identifiers' + +export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { + public readonly supportedIdentifier = indyVdrAnonCredsRegistryIdentifierRegex + + public async getSchema(agentContext: AgentContext, schemaId: string): Promise { + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const did = didFromSchemaId(schemaId) + + const pool = await indyVdrPoolService.getPoolForDid(agentContext, did) + + agentContext.config.logger.debug(`Getting schema '${schemaId}' from ledger '${pool.indyNamespace}'`) + const request = new GetSchemaRequest({ submitterDid: did, schemaId }) + + agentContext.config.logger.trace( + `Submitting get schema request for schema '${schemaId}' to ledger '${pool.indyNamespace}'` + ) + const response = await pool.submitReadRequest(request) + + agentContext.config.logger.trace(`Got un-parsed schema '${schemaId}' from ledger '${pool.indyNamespace}'`, { + response, + }) + + const issuerId = didFromSchemaId(schemaId) + + if ('attr_names' in response.result.data) { return { - schemaId, - resolutionMetadata: { - error: 'notFound', - message: `unable to find schema with id ${schemaId}`, + schema: { + attrNames: response.result.data.attr_names, + name: response.result.data.name, + version: response.result.data.version, + issuerId, }, - schemaMetadata: {} - } - - } catch (error) { - agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`, { - error, - schemaId, - }) - - return { - schemaId, - resolutionMetadata: { - error: 'notFound', - message: `unable to resolve credential definition: ${error.message}`, + schemaId: schemaId, + resolutionMetadata: {}, + schemaMetadata: { + didIndyNamespace: pool.indyNamespace, + // NOTE: the seqNo is required by the indy-sdk even though not present in AnonCreds v1. + // For this reason we return it in the metadata. + indyLedgerSeqNo: response.result.seqNo, }, - schemaMetadata: {}, } } + + agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`) + + return { + schemaId, + resolutionMetadata: { + error: 'notFound', + message: `unable to find schema with id ${schemaId}`, + }, + schemaMetadata: {}, + } + } catch (error) { + agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`, { + error, + schemaId, + }) + + return { + schemaId, + resolutionMetadata: { + error: 'notFound', + }, + schemaMetadata: {}, + } + } + } + + public async registerSchema( + agentContext: AgentContext, + options: IndyVdrRegisterSchemaOptions + ): Promise { + if (!options.options.didIndyNamespace) { + return { + schemaMetadata: {}, + registrationMetadata: {}, + schemaState: { + reason: 'no didIndyNamespace defined in the options. didIndyNamespace is required when using the Indy VDR', + schema: options.schema, + state: 'failed', + }, + } } - - public async registerSchema( - agentContext: AgentContext, - options: IndyVdrRegisterSchemaOptions - ): Promise { - if (!options.options.didIndyNamespace) { + + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const schemaRequest = new SchemaRequest({ + submitterDid: options.schema.issuerId, + schema: { + id: getLegacySchemaId(options.schema.issuerId, options.schema.name, options.schema.version), + name: options.schema.name, + ver: '1.0', + version: options.schema.version, + attrNames: options.schema.attrNames, + }, + }) + + const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace) + + // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did + // from the ledger to know which key is associated with the did + // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did + // from the ledger to know which key is associated with the did + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didResult = await didsApi.resolve(`did:sov:${options.schema.issuerId}`) + + if (!didResult.didDocument) { return { schemaMetadata: {}, registrationMetadata: {}, schemaState: { - reason: 'no didIndyNamespace defined in the options. didIndyNamespace is required when using the Indy VDR', schema: options.schema, state: 'failed', + reason: `didNotFound: unable to resolve did did:sov${options.schema.issuerId}: ${didResult.didResolutionMetadata.message}`, }, } } - - try { - const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) - - const schemaRequest = new SchemaRequest({ - submitterDid: options.schema.issuerId, - schema: { - id: getLegacySchemaId(options.schema.issuerId, options.schema.name, options.schema.version), - name: options.schema.name, - ver: '1.0', - version: options.schema.version, - attrNames: options.schema.attrNames, - }, - }) - - const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace); - - // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did - // from the ledger to know which key is associated with the did - // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did - // from the ledger to know which key is associated with the did - const didsApi = agentContext.dependencyManager.resolve(DidsApi) - const didResult = await didsApi.resolve(`did:sov:${options.schema.issuerId}`) - - if (!didResult.didDocument) throw new AriesFrameworkError('Unable to resolve did') - + const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) const key = getKeyFromVerificationMethod(verificationMethod) - + const response = await pool.submitWriteRequest(agentContext, schemaRequest, key) - + return { schemaState: { state: 'finished', @@ -153,223 +174,256 @@ import type { indyLedgerSeqNo: response.result.txnMetadata.seqNo, didIndyNamespace: pool.indyNamespace, }, - } - - - } catch (error) { - agentContext.config.logger.error(`Error registering schema for did '${options.schema.issuerId}'`, { - error, - did: options.schema.issuerId, + } catch (error) { + agentContext.config.logger.error(`Error registering schema for did '${options.schema.issuerId}'`, { + error, + did: options.schema.issuerId, + schema: options.schema, + }) + + return { + schemaMetadata: {}, + registrationMetadata: {}, + schemaState: { + state: 'failed', schema: options.schema, - }) - - return { - schemaMetadata: {}, - registrationMetadata: {}, - schemaState: { - state: 'failed', - schema: options.schema, - reason: `unknownError: ${error.message}`, - }, - } + reason: `unknownError: ${error.message}`, + }, } } - - public async getCredentialDefinition( - agentContext: AgentContext, - credentialDefinitionId: string - ): Promise { - try { - const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) - - const did = didFromCredentialDefinitionId(credentialDefinitionId) - - const pool = await indyVdrPoolService.getPoolForDid(agentContext, did) - - agentContext.config.logger.debug( - `Getting credential definition '${credentialDefinitionId}' from ledger '${pool.indyNamespace}'` - ) - - const request = new GetCredentialDefinitionRequest({ - submitterDid: did, - credentialDefinitionId - }); - - agentContext.config.logger.trace( - `Submitting get credential definition request for credential definition '${credentialDefinitionId}' to ledger '${pool.indyNamespace}'` - ) - - const response = await pool.submitReadRequest(request) - - if (response.result.data) { - return { - credentialDefinitionId: credentialDefinitionId, - credentialDefinition: { - issuerId: didFromCredentialDefinitionId(credentialDefinitionId), - schemaId: response.result.ref.toString(), - tag: response.result.tag, - type: 'CL', - value: response.result.data, - }, - credentialDefinitionMetadata: { - didIndyNamespace: pool.indyNamespace, - }, - resolutionMetadata: {}, - } - } - - agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`) - + } + + public async getCredentialDefinition( + agentContext: AgentContext, + credentialDefinitionId: string + ): Promise { + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const did = didFromCredentialDefinitionId(credentialDefinitionId) + + const pool = await indyVdrPoolService.getPoolForDid(agentContext, did) + + agentContext.config.logger.debug( + `Getting credential definition '${credentialDefinitionId}' from ledger '${pool.indyNamespace}'` + ) + + const request = new GetCredentialDefinitionRequest({ + submitterDid: did, + credentialDefinitionId, + }) + + agentContext.config.logger.trace( + `Submitting get credential definition request for credential definition '${credentialDefinitionId}' to ledger '${pool.indyNamespace}'` + ) + + const response = await pool.submitReadRequest(request) + + if (response.result.data) { return { - credentialDefinitionId, - credentialDefinitionMetadata: {}, - resolutionMetadata: { - error: 'notFound', - message: `unable to resolve credential definition with id ${credentialDefinitionId}`, + credentialDefinitionId: credentialDefinitionId, + credentialDefinition: { + issuerId: didFromCredentialDefinitionId(credentialDefinitionId), + schemaId: response.result.ref.toString(), + tag: response.result.tag, + type: 'CL', + value: response.result.data, }, - } - - } catch (error) { - agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`, { - error, - credentialDefinitionId, - }) - - return { - credentialDefinitionId, - credentialDefinitionMetadata: {}, - resolutionMetadata: { - error: 'notFound', - message: `unable to resolve credential definition: ${error.message}`, + credentialDefinitionMetadata: { + didIndyNamespace: pool.indyNamespace, }, + resolutionMetadata: {}, } } + + agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`) + + return { + credentialDefinitionId, + credentialDefinitionMetadata: {}, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve credential definition with id ${credentialDefinitionId}`, + }, + } + } catch (error) { + agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`, { + error, + credentialDefinitionId, + }) + + return { + credentialDefinitionId, + credentialDefinitionMetadata: {}, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve credential definition: ${error.message}`, + }, + } } - - public async registerCredentialDefinition(agentContext: AgentContext, options: IndyVdrRegisterCredentialDefinitionOptions): Promise { - // Make sure didIndyNamespace is passed - if (!options.options.didIndyNamespace) { - return { - credentialDefinitionMetadata: {}, - registrationMetadata: {}, - credentialDefinitionState: { - reason: 'no didIndyNamespace defined in the options. didIndyNamespace is required when using the Indy SDK', - credentialDefinition: options.credentialDefinition, - state: 'failed', - }, - } + } + + public async registerCredentialDefinition( + agentContext: AgentContext, + options: IndyVdrRegisterCredentialDefinitionOptions + ): Promise { + // Make sure didIndyNamespace is passed + if (!options.options.didIndyNamespace) { + return { + credentialDefinitionMetadata: {}, + registrationMetadata: {}, + credentialDefinitionState: { + reason: 'no didIndyNamespace defined in the options. didIndyNamespace is required when using the Indy SDK', + credentialDefinition: options.credentialDefinition, + state: 'failed', + }, } - - try { - const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService); - - //TODO: get schema SeqNo - const credentialDefinitionId = getLegacyCredentialDefinitionId(options.options.didIndyNamespace, options.credentialDefinition., options.credentialDefinition.tag), - - const credentialDefinitionRequest = new CredentialDefinitionRequest({ - submitterDid: options.credentialDefinition.issuerId, - credentialDefinition: { - ver: '1.0', - id: credentialDefinitionId, - schemaId: options.credentialDefinition.schemaId, - type: 'CL', - tag: options.credentialDefinition.tag, - value: { - primary: options.credentialDefinition.value, - - }, - }, - }) - - const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace); - - const didsApi = agentContext.dependencyManager.resolve(DidsApi) - const didResult = await didsApi.resolve(`did:sov:${options.credentialDefinition.issuerId}`) - - if (!didResult.didDocument) throw new AriesFrameworkError('Unable to resolve did') - - const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') - const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) - const key = getKeyFromVerificationMethod(verificationMethod) - - const response = await pool.submitWriteRequest(agentContext, credentialDefinitionRequest, key); - - agentContext.config.logger.debug( - `Registered credential definition '${credentialDefinitionId}' on ledger '${pool.indyNamespace}'`, - { - response, - credentialDefinition: options.credentialDefinition, - } - ) - + } + + try { + const indyVdrPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + + const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace) + + const { schema, schemaMetadata, resolutionMetadata } = await this.getSchema( + agentContext, + options.credentialDefinition.schemaId + ) + + if (!schema || !schemaMetadata.indyLedgerSeqNo || typeof schemaMetadata.indyLedgerSeqNo !== 'number') { return { + registrationMetadata: {}, credentialDefinitionMetadata: { didIndyNamespace: pool.indyNamespace, }, credentialDefinitionState: { credentialDefinition: options.credentialDefinition, - credentialDefinitionId, - state: 'finished', + state: 'failed', + reason: `error resolving schema with id ${options.credentialDefinition.schemaId}: ${resolutionMetadata.error} ${resolutionMetadata.message}`, }, - registrationMetadata: {}, } - } catch (error) { - agentContext.config.logger.error( - `Error registering credential definition for schema '${options.credentialDefinition.schemaId}'`, - { - error, - did: options.credentialDefinition.issuerId, - credentialDefinition: options.credentialDefinition, - } - ) - + } + + const credentialDefinitionId = getLegacyCredentialDefinitionId( + options.options.didIndyNamespace, + schemaMetadata.indyLedgerSeqNo, + options.credentialDefinition.tag + ) + + const credentialDefinitionRequest = new CredentialDefinitionRequest({ + submitterDid: options.credentialDefinition.issuerId, + credentialDefinition: { + ver: '1.0', + id: credentialDefinitionId, + schemaId: options.credentialDefinition.schemaId, + type: 'CL', + tag: options.credentialDefinition.tag, + value: { + primary: options.credentialDefinition.value, + }, + }, + }) + + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didResult = await didsApi.resolve(`did:sov:${options.credentialDefinition.issuerId}`) + + if (!didResult.didDocument) { return { credentialDefinitionMetadata: {}, registrationMetadata: {}, credentialDefinitionState: { credentialDefinition: options.credentialDefinition, state: 'failed', - reason:`unknownError: ${error.message}` - } + reason: `didNotFound: unable to resolve did did:sov${options.credentialDefinition.issuerId}: ${didResult.didResolutionMetadata.message}`, + }, } } - } - - public async getRevocationList(agentContext: AgentContext, revocationRegistryId: string, timestamp: number): Promise { + + const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') + const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) + const key = getKeyFromVerificationMethod(verificationMethod) + + const response = await pool.submitWriteRequest(agentContext, credentialDefinitionRequest, key) + + agentContext.config.logger.debug( + `Registered credential definition '${credentialDefinitionId}' on ledger '${pool.indyNamespace}'`, + { + response, + credentialDefinition: options.credentialDefinition, + } + ) + return { - resolutionMetadata: { - error: 'Not Implemented', - message: `Revocation list not yet implemented `, + credentialDefinitionMetadata: { + didIndyNamespace: pool.indyNamespace, }, - revocationListMetadata: {}, + credentialDefinitionState: { + credentialDefinition: options.credentialDefinition, + credentialDefinitionId, + state: 'finished', + }, + registrationMetadata: {}, } - } - - public async getRevocationRegistryDefinition( - agentContext: AgentContext, - revocationRegistryDefinitionId: string - ): Promise { + } catch (error) { + agentContext.config.logger.error( + `Error registering credential definition for schema '${options.credentialDefinition.schemaId}'`, + { + error, + did: options.credentialDefinition.issuerId, + credentialDefinition: options.credentialDefinition, + } + ) + return { - resolutionMetadata: { - error: 'Not Implemented', - message: `Revocation registry definition not yet implemented`, + credentialDefinitionMetadata: {}, + registrationMetadata: {}, + credentialDefinitionState: { + credentialDefinition: options.credentialDefinition, + state: 'failed', + reason: `unknownError: ${error.message}`, }, - revocationRegistryDefinitionId, - revocationRegistryDefinitionMetadata: {}, } } } - - export interface IndyVdrRegisterSchemaOptions extends RegisterSchemaOptions { - options: { - didIndyNamespace: string + + public async getRevocationList( + agentContext: AgentContext, + revocationRegistryId: string, + timestamp: number + ): Promise { + return { + resolutionMetadata: { + error: 'Not Implemented', + message: `Revocation list not yet implemented `, + }, + revocationListMetadata: {}, } } - - export interface IndyVdrRegisterCredentialDefinitionOptions extends RegisterCredentialDefinitionOptions { - options: { - didIndyNamespace: string + + public async getRevocationRegistryDefinition( + agentContext: AgentContext, + revocationRegistryDefinitionId: string + ): Promise { + return { + resolutionMetadata: { + error: 'Not Implemented', + message: `Revocation registry definition not yet implemented`, + }, + revocationRegistryDefinitionId, + revocationRegistryDefinitionMetadata: {}, } } - \ No newline at end of file +} + +export interface IndyVdrRegisterSchemaOptions extends RegisterSchemaOptions { + options: { + didIndyNamespace: string + } +} + +export interface IndyVdrRegisterCredentialDefinitionOptions extends RegisterCredentialDefinitionOptions { + options: { + didIndyNamespace: string + } +} diff --git a/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts b/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts index e3da8f05a1..62528a0075 100644 --- a/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts +++ b/packages/indy-vdr/src/anoncreds/utils/_tests_/identifier.test.ts @@ -1,49 +1,52 @@ -import {getLegacySchemaId, getLegacyCredentialDefinitionId, didFromSchemaId, didFromCredentialDefinitionId, indyVdrAnonCredsRegistryIdentifierRegex} from '../identifiers' +import { + getLegacySchemaId, + getLegacyCredentialDefinitionId, + didFromSchemaId, + didFromCredentialDefinitionId, + indyVdrAnonCredsRegistryIdentifierRegex, +} from '../identifiers' describe('identifiers', () => { - it('matches against a legacy indy did, schema id, credential definition id and revocation registry id', () => { - const did = '7Tqg6BwSSWapxgUDm9KKgg' - const schemaId = 'BQ42WeE24jFHeyGg8x9XAz:2:Medical Bill:1.0' - const credentialDefinitionId = 'N7baRMcyvPwWc8v85CtZ6e:3:CL:100669:SCH Employee ID' - const revocationRegistryId = - 'N7baRMcyvPwWc8v85CtZ6e:4:N7baRMcyvPwWc8v85CtZ6e:3:CL:100669:SCH Employee ID:CL_ACCUM:1-1024' - - const anotherId = 'some:id' - - expect(indyVdrAnonCredsRegistryIdentifierRegex.test(did)).toEqual(true) - expect(indyVdrAnonCredsRegistryIdentifierRegex.test(schemaId)).toEqual(true) - expect(indyVdrAnonCredsRegistryIdentifierRegex.test(credentialDefinitionId)).toEqual(true) - expect(indyVdrAnonCredsRegistryIdentifierRegex.test(revocationRegistryId)).toEqual(true) - expect(indyVdrAnonCredsRegistryIdentifierRegex.test(anotherId)).toEqual(false) - }) - - it('getLegacySchemaId should return a valid schema Id', () => { - const did = '29347' - const name = 'starlinks' - const version = '321' - - expect(getLegacySchemaId(did, name, version)).toEqual(`29347:2:starlinks:321`) - }) - - it ('getLegacyCredentialDefinition should return a valid Credential Id', () => { - - const did = '15565' - const seqNo = 323 - const tag = 'indyTag' - expect(getLegacyCredentialDefinitionId(did, seqNo, tag)).toEqual('15565:3:CL:323:indyTag') - }) - - it ('didFromSchemaId should return the valid did from the schema', () => { - const schemaId = '29347:2:starlinks:321' - - expect(didFromSchemaId(schemaId)).toEqual('29347') - }) - - it ('didFromCredentialId should return the valid did from the schema', () => { - const credentialDefinitionId = '15565:3:CL:323:indyTag' - - expect(didFromCredentialDefinitionId(credentialDefinitionId)).toEqual('15565') - }) - - -}) \ No newline at end of file + it('matches against a legacy indy did, schema id, credential definition id and revocation registry id', () => { + const did = '7Tqg6BwSSWapxgUDm9KKgg' + const schemaId = 'BQ42WeE24jFHeyGg8x9XAz:2:Medical Bill:1.0' + const credentialDefinitionId = 'N7baRMcyvPwWc8v85CtZ6e:3:CL:100669:SCH Employee ID' + const revocationRegistryId = + 'N7baRMcyvPwWc8v85CtZ6e:4:N7baRMcyvPwWc8v85CtZ6e:3:CL:100669:SCH Employee ID:CL_ACCUM:1-1024' + + const anotherId = 'some:id' + + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(did)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(schemaId)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(credentialDefinitionId)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(revocationRegistryId)).toEqual(true) + expect(indyVdrAnonCredsRegistryIdentifierRegex.test(anotherId)).toEqual(false) + }) + + it('getLegacySchemaId should return a valid schema Id', () => { + const did = '29347' + const name = 'starlinks' + const version = '321' + + expect(getLegacySchemaId(did, name, version)).toEqual(`29347:2:starlinks:321`) + }) + + it('getLegacyCredentialDefinition should return a valid Credential Id', () => { + const did = '15565' + const seqNo = 323 + const tag = 'indyTag' + expect(getLegacyCredentialDefinitionId(did, seqNo, tag)).toEqual('15565:3:CL:323:indyTag') + }) + + it('didFromSchemaId should return the valid did from the schema', () => { + const schemaId = '29347:2:starlinks:321' + + expect(didFromSchemaId(schemaId)).toEqual('29347') + }) + + it('didFromCredentialId should return the valid did from the schema', () => { + const credentialDefinitionId = '15565:3:CL:323:indyTag' + + expect(didFromCredentialDefinitionId(credentialDefinitionId)).toEqual('15565') + }) +}) diff --git a/packages/indy-vdr/src/anoncreds/utils/identifiers.ts b/packages/indy-vdr/src/anoncreds/utils/identifiers.ts index ce240883e1..ac033cd4e6 100644 --- a/packages/indy-vdr/src/anoncreds/utils/identifiers.ts +++ b/packages/indy-vdr/src/anoncreds/utils/identifiers.ts @@ -6,31 +6,31 @@ export const legacyIndyVdrRevocationRegistryIdRegex = /^[a-zA-Z0-9]{21,22}:4:[a-zA-Z0-9]{21,22}:3:CL:(([1-9][0-9]*)|([a-zA-Z0-9]{21,22}:2:.+:[0-9.]+))(:.+)?:CL_ACCUM:(.+$)/ export const indyVdrAnonCredsRegistryIdentifierRegex = new RegExp( - `${legacyIndyVdrIssuerIdRegex.source}|${legacyIndyVdrSchemaIdRegex.source}|${legacyIndyVdrCredentialDefinitionIdRegex.source}|${legacyIndyVdrRevocationRegistryIdRegex.source}` - ) + `${legacyIndyVdrIssuerIdRegex.source}|${legacyIndyVdrSchemaIdRegex.source}|${legacyIndyVdrCredentialDefinitionIdRegex.source}|${legacyIndyVdrRevocationRegistryIdRegex.source}` +) export function getLegacySchemaId(unqualifiedDid: string, name: string, version: string) { - return `${unqualifiedDid}:2:${name}:${version}` - } - - export function getLegacyCredentialDefinitionId(unqualifiedDid: string, seqNo: number, tag: string) { - return `${unqualifiedDid}:3:CL:${seqNo}:${tag}` - } + return `${unqualifiedDid}:2:${name}:${version}` +} - /** +export function getLegacyCredentialDefinitionId(unqualifiedDid: string, seqNo: number, tag: string) { + return `${unqualifiedDid}:3:CL:${seqNo}:${tag}` +} + +/** * Extract did from schema id */ export function didFromSchemaId(schemaId: string) { - const [did] = schemaId.split(':') - - return did - } - - /** - * Extract did from credential definition id - */ - export function didFromCredentialDefinitionId(credentialDefinitionId: string) { - const [did] = credentialDefinitionId.split(':') - - return did - } \ No newline at end of file + const [did] = schemaId.split(':') + + return did +} + +/** + * Extract did from credential definition id + */ +export function didFromCredentialDefinitionId(credentialDefinitionId: string) { + const [did] = credentialDefinitionId.split(':') + + return did +} From 78d514327bb81f50f9b80eea2b2ad3c17325200a Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Tue, 7 Feb 2023 17:04:40 +0100 Subject: [PATCH 05/11] fix: change revocation list name convention work funded by the Government of Ontario Signed-off-by: Victor Anene --- .../indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts index 2f5c5dbf3d..7e3d7950ca 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts @@ -6,7 +6,7 @@ import type { RegisterCredentialDefinitionOptions, RegisterSchemaReturn, RegisterCredentialDefinitionReturn, - GetRevocationListReturn, + GetRevocationStatusListReturn, GetRevocationRegistryDefinitionReturn, } from '@aries-framework/anoncreds' import type { AgentContext } from '@aries-framework/core' @@ -387,17 +387,17 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { } } - public async getRevocationList( + public async getRevocationStatusList( agentContext: AgentContext, revocationRegistryId: string, timestamp: number - ): Promise { + ): Promise { return { resolutionMetadata: { error: 'Not Implemented', message: `Revocation list not yet implemented `, }, - revocationListMetadata: {}, + revocationStatusListMetadata: {}, } } From 86b9ecaf4973d7d2a488bed90013a0e03cc843b7 Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Thu, 9 Feb 2023 01:45:22 +0100 Subject: [PATCH 06/11] feat(indy-vdr): revocation methods for the IndyVdrAnoncCredsRegsitry Work funded by the Government of Ontario Signed-off-by: Victor Anene --- .../src/anoncreds/indyVdrAnoncredsRegistry.ts | 150 ++++++++++++++++-- .../src/anoncreds/utils/identifiers.ts | 6 + 2 files changed, 141 insertions(+), 15 deletions(-) diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts index 7e3d7950ca..c97d06ea3f 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts @@ -13,10 +13,12 @@ import type { AgentContext } from '@aries-framework/core' import { DidsApi, getKeyDidMappingByVerificationMethod } from '@aries-framework/core' import { - CredentialDefinitionRequest, GetSchemaRequest, - GetCredentialDefinitionRequest, SchemaRequest, + GetCredentialDefinitionRequest, + CredentialDefinitionRequest, + GetRevocationRegistryDefinitionRequest, + GetRevocationRegistryDeltaRequest, } from '@hyperledger/indy-vdr-shared' import { IndyVdrPoolService } from '../pool' @@ -27,6 +29,7 @@ import { getLegacySchemaId, getLegacyCredentialDefinitionId, indyVdrAnonCredsRegistryIdentifierRegex, + didFromRevocationRegistryDefinitionId, } from './utils/identifiers' export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { @@ -392,12 +395,90 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { revocationRegistryId: string, timestamp: number ): Promise { - return { - resolutionMetadata: { - error: 'Not Implemented', - message: `Revocation list not yet implemented `, - }, - revocationStatusListMetadata: {}, + try { + const indySdkPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + const did = didFromRevocationRegistryDefinitionId(revocationRegistryId) + + const pool = await indySdkPoolService.getPoolForDid(agentContext, did) + + agentContext.config.logger.debug( + `Using ledger '${pool.indyNamespace}' to retrieve revocation registry deltas with revocation registry definition id '${revocationRegistryId}' until ${timestamp}` + ) + + const request = new GetRevocationRegistryDeltaRequest({ + submitterDid: did, + revocationRegistryId, + toTs: timestamp, + }) + + agentContext.config.logger.trace( + `Submitting get revocation registry delta request for revocation registry '${revocationRegistryId}' to ledger` + ) + + const response = await pool.submitReadRequest(request) + + agentContext.config.logger.debug( + `Got revocation registry deltas '${revocationRegistryId}' until timestamp ${timestamp} from ledger` + ) + + const { resolutionMetadata, revocationRegistryDefinitionMetadata } = await this.getRevocationRegistryDefinition( + agentContext, + revocationRegistryId + ) + + if ( + !revocationRegistryDefinitionMetadata.issuanceType || + typeof revocationRegistryDefinitionMetadata.issuanceType !== 'string' + ) { + return { + resolutionMetadata: { + error: `error resolving revocation registry definition with id ${revocationRegistryId}: ${resolutionMetadata.error} ${resolutionMetadata.message}`, + }, + revocationStatusListMetadata: { + didIndyNamespace: pool.indyNamespace, + }, + } + } + + if (!response.result.data) { + return { + resolutionMetadata: { + error: 'notFound', + message: `Error retrieving revocation registry delta '${revocationRegistryId}' from ledger, potentially revocation interval ends before revocation registry creation`, + }, + revocationStatusListMetadata: {}, + } + } + + return { + resolutionMetadata: {}, + revocationStatusList: { + issuerId: response.result.identifier, + revRegId: response.result.revocRegDefId, + currentAccumulator: response.result.data.value.accum_to.value.accum, + revocationList: response.result.data?.value.revoked, + timestamp: response.result.data.value.accum_to.txnTime, + }, + revocationStatusListMetadata: { + didIndyNamespace: pool.indyNamespace, + }, + } + } catch (error) { + agentContext.config.logger.error( + `Error retrieving revocation registry delta '${revocationRegistryId}' from ledger, potentially revocation interval ends before revocation registry creation?"`, + { + error, + revocationRegistryId: revocationRegistryId, + } + ) + + return { + resolutionMetadata: { + error: 'notFound', + message: `Error retrieving revocation registry delta '${revocationRegistryId}' from ledger, potentially revocation interval ends before revocation registry creation: ${error.message}`, + }, + revocationStatusListMetadata: {}, + } } } @@ -405,13 +486,52 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { agentContext: AgentContext, revocationRegistryDefinitionId: string ): Promise { - return { - resolutionMetadata: { - error: 'Not Implemented', - message: `Revocation registry definition not yet implemented`, - }, - revocationRegistryDefinitionId, - revocationRegistryDefinitionMetadata: {}, + try { + const indySdkPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) + const did = didFromRevocationRegistryDefinitionId(revocationRegistryDefinitionId) + + const pool = await indySdkPoolService.getPoolForDid(agentContext, did) + + agentContext.config.logger.debug( + `Using ledger '${pool.indyNamespace}' to retrieve revocation registry definition '${revocationRegistryDefinitionId}'` + ) + + const request = new GetRevocationRegistryDefinitionRequest({ + submitterDid: did, + revocationRegistryId: revocationRegistryDefinitionId, + }) + + agentContext.config.logger.trace( + `Submitting get revocation registry definition request for revocation registry definition '${revocationRegistryDefinitionId}' to ledger` + ) + + const response = await pool.submitReadRequest(request) + + return { + revocationRegistryDefinitionId, + revocationRegistryDefinitionMetadata: { + issuanceType: response.result.data?.value.issuanceType, + didIndyNamespace: pool.indyNamespace, + }, + resolutionMetadata: {}, + } + } catch (error) { + agentContext.config.logger.error( + `Error retrieving revocation registry definition '${revocationRegistryDefinitionId}' from ledger`, + { + error, + revocationRegistryDefinitionId, + } + ) + + return { + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve revocation registry definition: ${error.message}`, + }, + revocationRegistryDefinitionId, + revocationRegistryDefinitionMetadata: {}, + } } } } diff --git a/packages/indy-vdr/src/anoncreds/utils/identifiers.ts b/packages/indy-vdr/src/anoncreds/utils/identifiers.ts index ac033cd4e6..d242ca3461 100644 --- a/packages/indy-vdr/src/anoncreds/utils/identifiers.ts +++ b/packages/indy-vdr/src/anoncreds/utils/identifiers.ts @@ -34,3 +34,9 @@ export function didFromCredentialDefinitionId(credentialDefinitionId: string) { return did } + +export function didFromRevocationRegistryDefinitionId(revocationRegistryId: string) { + const [did] = revocationRegistryId.split(':') + + return did +} From c4e5e0ded4ed312ec6ea7fed42824feffedad850 Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Thu, 9 Feb 2023 16:48:38 +0100 Subject: [PATCH 07/11] refactor(indy-vdr): remove revocation methods work funded by the Govenment of Ontario Signed-off-by: Victor Anene --- .../src/anoncreds/indyVdrAnoncredsRegistry.ts | 143 ++---------------- 1 file changed, 13 insertions(+), 130 deletions(-) diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts index c97d06ea3f..5983725235 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts @@ -395,90 +395,12 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { revocationRegistryId: string, timestamp: number ): Promise { - try { - const indySdkPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) - const did = didFromRevocationRegistryDefinitionId(revocationRegistryId) - - const pool = await indySdkPoolService.getPoolForDid(agentContext, did) - - agentContext.config.logger.debug( - `Using ledger '${pool.indyNamespace}' to retrieve revocation registry deltas with revocation registry definition id '${revocationRegistryId}' until ${timestamp}` - ) - - const request = new GetRevocationRegistryDeltaRequest({ - submitterDid: did, - revocationRegistryId, - toTs: timestamp, - }) - - agentContext.config.logger.trace( - `Submitting get revocation registry delta request for revocation registry '${revocationRegistryId}' to ledger` - ) - - const response = await pool.submitReadRequest(request) - - agentContext.config.logger.debug( - `Got revocation registry deltas '${revocationRegistryId}' until timestamp ${timestamp} from ledger` - ) - - const { resolutionMetadata, revocationRegistryDefinitionMetadata } = await this.getRevocationRegistryDefinition( - agentContext, - revocationRegistryId - ) - - if ( - !revocationRegistryDefinitionMetadata.issuanceType || - typeof revocationRegistryDefinitionMetadata.issuanceType !== 'string' - ) { - return { - resolutionMetadata: { - error: `error resolving revocation registry definition with id ${revocationRegistryId}: ${resolutionMetadata.error} ${resolutionMetadata.message}`, - }, - revocationStatusListMetadata: { - didIndyNamespace: pool.indyNamespace, - }, - } - } - - if (!response.result.data) { - return { - resolutionMetadata: { - error: 'notFound', - message: `Error retrieving revocation registry delta '${revocationRegistryId}' from ledger, potentially revocation interval ends before revocation registry creation`, - }, - revocationStatusListMetadata: {}, - } - } - - return { - resolutionMetadata: {}, - revocationStatusList: { - issuerId: response.result.identifier, - revRegId: response.result.revocRegDefId, - currentAccumulator: response.result.data.value.accum_to.value.accum, - revocationList: response.result.data?.value.revoked, - timestamp: response.result.data.value.accum_to.txnTime, - }, - revocationStatusListMetadata: { - didIndyNamespace: pool.indyNamespace, - }, - } - } catch (error) { - agentContext.config.logger.error( - `Error retrieving revocation registry delta '${revocationRegistryId}' from ledger, potentially revocation interval ends before revocation registry creation?"`, - { - error, - revocationRegistryId: revocationRegistryId, - } - ) - - return { - resolutionMetadata: { - error: 'notFound', - message: `Error retrieving revocation registry delta '${revocationRegistryId}' from ledger, potentially revocation interval ends before revocation registry creation: ${error.message}`, - }, - revocationStatusListMetadata: {}, - } + return { + resolutionMetadata: { + error: 'Not Implemented', + message: `Revocation list not yet implemented `, + }, + revocationStatusListMetadata: {}, } } @@ -486,52 +408,13 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { agentContext: AgentContext, revocationRegistryDefinitionId: string ): Promise { - try { - const indySdkPoolService = agentContext.dependencyManager.resolve(IndyVdrPoolService) - const did = didFromRevocationRegistryDefinitionId(revocationRegistryDefinitionId) - - const pool = await indySdkPoolService.getPoolForDid(agentContext, did) - - agentContext.config.logger.debug( - `Using ledger '${pool.indyNamespace}' to retrieve revocation registry definition '${revocationRegistryDefinitionId}'` - ) - - const request = new GetRevocationRegistryDefinitionRequest({ - submitterDid: did, - revocationRegistryId: revocationRegistryDefinitionId, - }) - - agentContext.config.logger.trace( - `Submitting get revocation registry definition request for revocation registry definition '${revocationRegistryDefinitionId}' to ledger` - ) - - const response = await pool.submitReadRequest(request) - - return { - revocationRegistryDefinitionId, - revocationRegistryDefinitionMetadata: { - issuanceType: response.result.data?.value.issuanceType, - didIndyNamespace: pool.indyNamespace, - }, - resolutionMetadata: {}, - } - } catch (error) { - agentContext.config.logger.error( - `Error retrieving revocation registry definition '${revocationRegistryDefinitionId}' from ledger`, - { - error, - revocationRegistryDefinitionId, - } - ) - - return { - resolutionMetadata: { - error: 'notFound', - message: `unable to resolve revocation registry definition: ${error.message}`, - }, - revocationRegistryDefinitionId, - revocationRegistryDefinitionMetadata: {}, - } + return { + resolutionMetadata: { + error: 'Not Implemented', + message: `Revocation registry definition not yet implemented`, + }, + revocationRegistryDefinitionId, + revocationRegistryDefinitionMetadata: {}, } } } From 9b5d9f4aaa3e20e8a20376914934621ce629d7f8 Mon Sep 17 00:00:00 2001 From: Victor Anene Date: Thu, 9 Feb 2023 17:32:11 +0100 Subject: [PATCH 08/11] fix(indy-vdr): resolve verification method work funded by the Govenment of Ontario Signed-off-by: Victor Anene --- packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts index 5983725235..5a3c7d0c4f 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts @@ -153,7 +153,7 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { } } - const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') + const verificationMethod = didResult.didDocument.dereferenceKey(`did:sov:${options.schema.issuerId}#key-1`) const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) const key = getKeyFromVerificationMethod(verificationMethod) @@ -342,8 +342,7 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { }, } } - - const verificationMethod = didResult.didDocument.dereferenceKey('did:sov:${issuerId}#key-1') + const verificationMethod = didResult.didDocument.dereferenceKey(`did:sov:${options.credentialDefinition.issuerId}#key-1`) const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) const key = getKeyFromVerificationMethod(verificationMethod) From 4155f8315f75cf9e8ae9979ae6dca2dafd726978 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Thu, 9 Feb 2023 17:52:24 +0100 Subject: [PATCH 09/11] test(indy-vdr): add anoncreds registry test Signed-off-by: Timo Glastra --- ...egistry.ts => IndyVdrAnonCredsRegistry.ts} | 18 +- .../indy-vdr-anoncreds-registry.e2e.test.ts | 190 ++++++++++++++++++ .../indy-vdr/tests/indy-vdr-pool.e2e.test.ts | 168 ++++++++-------- 3 files changed, 282 insertions(+), 94 deletions(-) rename packages/indy-vdr/src/anoncreds/{indyVdrAnoncredsRegistry.ts => IndyVdrAnonCredsRegistry.ts} (97%) create mode 100644 packages/indy-vdr/tests/indy-vdr-anoncreds-registry.e2e.test.ts diff --git a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts b/packages/indy-vdr/src/anoncreds/IndyVdrAnonCredsRegistry.ts similarity index 97% rename from packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts rename to packages/indy-vdr/src/anoncreds/IndyVdrAnonCredsRegistry.ts index 5a3c7d0c4f..1106b498cd 100644 --- a/packages/indy-vdr/src/anoncreds/indyVdrAnoncredsRegistry.ts +++ b/packages/indy-vdr/src/anoncreds/IndyVdrAnonCredsRegistry.ts @@ -17,8 +17,6 @@ import { SchemaRequest, GetCredentialDefinitionRequest, CredentialDefinitionRequest, - GetRevocationRegistryDefinitionRequest, - GetRevocationRegistryDeltaRequest, } from '@hyperledger/indy-vdr-shared' import { IndyVdrPoolService } from '../pool' @@ -29,7 +27,6 @@ import { getLegacySchemaId, getLegacyCredentialDefinitionId, indyVdrAnonCredsRegistryIdentifierRegex, - didFromRevocationRegistryDefinitionId, } from './utils/identifiers' export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { @@ -134,8 +131,6 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { const pool = indyVdrPoolService.getPoolForNamespace(options.options.didIndyNamespace) - // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did - // from the ledger to know which key is associated with the did // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did // from the ledger to know which key is associated with the did const didsApi = agentContext.dependencyManager.resolve(DidsApi) @@ -148,7 +143,7 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { schemaState: { schema: options.schema, state: 'failed', - reason: `didNotFound: unable to resolve did did:sov${options.schema.issuerId}: ${didResult.didResolutionMetadata.message}`, + reason: `didNotFound: unable to resolve did did:sov:${options.schema.issuerId}: ${didResult.didResolutionMetadata.message}`, }, } } @@ -309,7 +304,7 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { } const credentialDefinitionId = getLegacyCredentialDefinitionId( - options.options.didIndyNamespace, + options.credentialDefinition.issuerId, schemaMetadata.indyLedgerSeqNo, options.credentialDefinition.tag ) @@ -319,7 +314,7 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { credentialDefinition: { ver: '1.0', id: credentialDefinitionId, - schemaId: options.credentialDefinition.schemaId, + schemaId: `${schemaMetadata.indyLedgerSeqNo}`, type: 'CL', tag: options.credentialDefinition.tag, value: { @@ -328,6 +323,8 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { }, }) + // FIXME: we should store the didDocument in the DidRecord so we don't have to fetch our own did + // from the ledger to know which key is associated with the did const didsApi = agentContext.dependencyManager.resolve(DidsApi) const didResult = await didsApi.resolve(`did:sov:${options.credentialDefinition.issuerId}`) @@ -342,7 +339,10 @@ export class IndyVdrAnonCredsRegistry implements AnonCredsRegistry { }, } } - const verificationMethod = didResult.didDocument.dereferenceKey(`did:sov:${options.credentialDefinition.issuerId}#key-1`) + + const verificationMethod = didResult.didDocument.dereferenceKey( + `did:sov:${options.credentialDefinition.issuerId}#key-1` + ) const { getKeyFromVerificationMethod } = getKeyDidMappingByVerificationMethod(verificationMethod) const key = getKeyFromVerificationMethod(verificationMethod) diff --git a/packages/indy-vdr/tests/indy-vdr-anoncreds-registry.e2e.test.ts b/packages/indy-vdr/tests/indy-vdr-anoncreds-registry.e2e.test.ts new file mode 100644 index 0000000000..9d214ea43d --- /dev/null +++ b/packages/indy-vdr/tests/indy-vdr-anoncreds-registry.e2e.test.ts @@ -0,0 +1,190 @@ +import { Agent } from '@aries-framework/core' + +import { agentDependencies, genesisTransactions, getAgentConfig } from '../../core/tests/helpers' +import { IndyVdrAnonCredsRegistry } from '../src/anoncreds/IndyVdrAnonCredsRegistry' +import { IndyVdrPoolService } from '../src/pool' + +const agentConfig = getAgentConfig('IndyVdrAnonCredsRegistry') + +// TODO: update to module once available +const indyVdrPoolService = new IndyVdrPoolService(agentConfig.logger) +indyVdrPoolService.setPools([ + { + genesisTransactions, + indyNamespace: 'local:test', + isProduction: false, + transactionAuthorAgreement: { version: '1', acceptanceMechanism: 'accept' }, + }, +]) + +const indyVdrAnonCredsRegistry = new IndyVdrAnonCredsRegistry() + +const agent = new Agent({ + config: agentConfig, + dependencies: agentDependencies, +}) + +agent.dependencyManager.registerInstance(IndyVdrPoolService, indyVdrPoolService) + +describe('IndyVdrAnonCredsRegistry', () => { + beforeAll(async () => { + await agent.initialize() + await indyVdrPoolService.connectToPools() + }) + + afterAll(async () => { + for (const pool of indyVdrPoolService.pools) { + pool.close() + } + + await agent.shutdown() + await agent.wallet.delete() + }) + + // One test as the credential definition depends on the schema + test('register and resolve a schema and credential definition', async () => { + const dynamicVersion = `1.${Math.random() * 100}` + + const schemaResult = await indyVdrAnonCredsRegistry.registerSchema(agent.context, { + options: { + didIndyNamespace: 'local:test', + }, + schema: { + attrNames: ['age'], + issuerId: 'TL1EaPFCZ8Si5aUrqScBDt', + name: 'test', + version: dynamicVersion, + }, + }) + + expect(schemaResult).toMatchObject({ + schemaState: { + state: 'finished', + schema: { + attrNames: ['age'], + issuerId: 'TL1EaPFCZ8Si5aUrqScBDt', + name: 'test', + version: dynamicVersion, + }, + schemaId: `TL1EaPFCZ8Si5aUrqScBDt:2:test:${dynamicVersion}`, + }, + registrationMetadata: {}, + schemaMetadata: { + indyLedgerSeqNo: expect.any(Number), + didIndyNamespace: 'local:test', + }, + }) + + const schemaResponse = await indyVdrAnonCredsRegistry.getSchema( + agent.context, + schemaResult.schemaState.schemaId as string + ) + expect(schemaResponse).toMatchObject({ + schema: { + attrNames: ['age'], + name: 'test', + version: dynamicVersion, + issuerId: 'TL1EaPFCZ8Si5aUrqScBDt', + }, + schemaId: `TL1EaPFCZ8Si5aUrqScBDt:2:test:${dynamicVersion}`, + resolutionMetadata: {}, + schemaMetadata: { + didIndyNamespace: 'local:test', + indyLedgerSeqNo: expect.any(Number), + }, + }) + + const credentialDefinitionResult = await indyVdrAnonCredsRegistry.registerCredentialDefinition(agent.context, { + credentialDefinition: { + issuerId: 'TL1EaPFCZ8Si5aUrqScBDt', + tag: 'TAG', + schemaId: `TL1EaPFCZ8Si5aUrqScBDt:2:test:${dynamicVersion}`, + type: 'CL', + value: { + primary: { + n: '92511867718854414868106363741369833735017762038454769060600859608405811709675033445666654908195955460485998711087020152978597220168927505650092431295783175164390266561239892662085428655566792056852960599485298025843840058914610127716620252006466964070280255168745873592143068949458568751438337748294055976926080232538440619420568859737673474560851456027625679328271511966332808025880807996449998057729417608399774744254122385012832309402226532031122728445959276178939234308090390331654445053482963947804769291501664200141562885660084823885847247231002821472258218384342423605116504024514572826071246440130942849549441', + s: '80388543865249952799447792504739237616187770512259677275061283897050980768551818104137338144380636412773836688624071360386172349725818126495487584981520630638409717065318132420766896092370913800616033623618952639023946750307405126873476182540669638841562357523429245685476919178722373320218824590869735129801004394337640642997250464303104754942997839179333543643110326022824394934965538190976474473353762308333205671176627192797138375084260446324344637548455228161138089974447059481109651156379803576163576511072261388342837813901850712083922506433336723723235701670225584863772222447543742649328218950436824219992164', + r: { + age: '676933340341980399002624386891134393471002096508227567343731826159610079436978196421307099268754545293545727546242372579987825752872485684085629459107300175443328323289748793060894500514926703654606851666031895448970879827423190730510730624784665299646624113512701254199984520803796529034094958026048762178753193812250643294518237843809104055653333871102658177900702978008644780459400512716361564897282969982554031820285585105004870317861287847206222714589633178648982299799311192432563797220854755882933052881306804544233529886513105815543097685128456041780804442879272476590077760678785460726492895806240870944398', + master_secret: + '57770757113548032970308439965749734133430520933173186296299026579579930337912607419798836831937319372744879560676750427054135869214212225572618340088847222727882935159356459822445182287686057012197046378986248048722180093079919306125315662058290895629438767985427829790980355162853804522854494960613869765167538645624719923127052541372069255024631093663068055100579264049925388231368871107383977060590248865498902704546409806115171120555709438784189721957301548212242748685629860268468247494986146122636455769804467583612610341632602695197189514316033637331733820369170763954604394734655429769801516997967996980978751', + }, + rctxt: + '19574881057684356733946284215946569464410211018678168661028327420122678446653210056362495902735819742274128834330867933095119512313591151219353395069123546495720010325822330866859140765940839241212947354612836044244554152389691282543839111284006009168728161183863936810142428875817934316327118674532328892591410224676539770085459540786747902789677759379901079898127879301595929571621032704093287675668250862222728331030586585586110859977896767318814398026750215625180255041545607499673023585546720788973882263863911222208020438685873501025545464213035270207099419236974668665979962146355749687924650853489277747454993', + z: '18569464356833363098514177097771727133940629758890641648661259687745137028161881113251218061243607037717553708179509640909238773964066423807945164288256211132195919975343578956381001087353353060599758005375631247614777454313440511375923345538396573548499287265163879524050255226779884271432737062283353279122281220812931572456820130441114446870167673796490210349453498315913599982158253821945225264065364670730546176140788405935081171854642125236557475395879246419105888077042924382595999612137336915304205628167917473420377397118829734604949103124514367857266518654728464539418834291071874052392799652266418817991437', + }, + }, + }, + options: { + didIndyNamespace: 'local:test', + }, + }) + + expect(credentialDefinitionResult).toMatchObject({ + credentialDefinitionMetadata: { + didIndyNamespace: 'local:test', + }, + credentialDefinitionState: { + credentialDefinition: { + issuerId: 'TL1EaPFCZ8Si5aUrqScBDt', + tag: 'TAG', + schemaId: `TL1EaPFCZ8Si5aUrqScBDt:2:test:${dynamicVersion}`, + type: 'CL', + value: { + primary: { + n: '92511867718854414868106363741369833735017762038454769060600859608405811709675033445666654908195955460485998711087020152978597220168927505650092431295783175164390266561239892662085428655566792056852960599485298025843840058914610127716620252006466964070280255168745873592143068949458568751438337748294055976926080232538440619420568859737673474560851456027625679328271511966332808025880807996449998057729417608399774744254122385012832309402226532031122728445959276178939234308090390331654445053482963947804769291501664200141562885660084823885847247231002821472258218384342423605116504024514572826071246440130942849549441', + s: '80388543865249952799447792504739237616187770512259677275061283897050980768551818104137338144380636412773836688624071360386172349725818126495487584981520630638409717065318132420766896092370913800616033623618952639023946750307405126873476182540669638841562357523429245685476919178722373320218824590869735129801004394337640642997250464303104754942997839179333543643110326022824394934965538190976474473353762308333205671176627192797138375084260446324344637548455228161138089974447059481109651156379803576163576511072261388342837813901850712083922506433336723723235701670225584863772222447543742649328218950436824219992164', + r: { + age: '676933340341980399002624386891134393471002096508227567343731826159610079436978196421307099268754545293545727546242372579987825752872485684085629459107300175443328323289748793060894500514926703654606851666031895448970879827423190730510730624784665299646624113512701254199984520803796529034094958026048762178753193812250643294518237843809104055653333871102658177900702978008644780459400512716361564897282969982554031820285585105004870317861287847206222714589633178648982299799311192432563797220854755882933052881306804544233529886513105815543097685128456041780804442879272476590077760678785460726492895806240870944398', + master_secret: + '57770757113548032970308439965749734133430520933173186296299026579579930337912607419798836831937319372744879560676750427054135869214212225572618340088847222727882935159356459822445182287686057012197046378986248048722180093079919306125315662058290895629438767985427829790980355162853804522854494960613869765167538645624719923127052541372069255024631093663068055100579264049925388231368871107383977060590248865498902704546409806115171120555709438784189721957301548212242748685629860268468247494986146122636455769804467583612610341632602695197189514316033637331733820369170763954604394734655429769801516997967996980978751', + }, + rctxt: + '19574881057684356733946284215946569464410211018678168661028327420122678446653210056362495902735819742274128834330867933095119512313591151219353395069123546495720010325822330866859140765940839241212947354612836044244554152389691282543839111284006009168728161183863936810142428875817934316327118674532328892591410224676539770085459540786747902789677759379901079898127879301595929571621032704093287675668250862222728331030586585586110859977896767318814398026750215625180255041545607499673023585546720788973882263863911222208020438685873501025545464213035270207099419236974668665979962146355749687924650853489277747454993', + z: '18569464356833363098514177097771727133940629758890641648661259687745137028161881113251218061243607037717553708179509640909238773964066423807945164288256211132195919975343578956381001087353353060599758005375631247614777454313440511375923345538396573548499287265163879524050255226779884271432737062283353279122281220812931572456820130441114446870167673796490210349453498315913599982158253821945225264065364670730546176140788405935081171854642125236557475395879246419105888077042924382595999612137336915304205628167917473420377397118829734604949103124514367857266518654728464539418834291071874052392799652266418817991437', + }, + }, + }, + credentialDefinitionId: `TL1EaPFCZ8Si5aUrqScBDt:3:CL:${schemaResponse.schemaMetadata.indyLedgerSeqNo}:TAG`, + state: 'finished', + }, + registrationMetadata: {}, + }) + + const credentialDefinitionResponse = await indyVdrAnonCredsRegistry.getCredentialDefinition( + agent.context, + credentialDefinitionResult.credentialDefinitionState.credentialDefinitionId as string + ) + + expect(credentialDefinitionResponse).toMatchObject({ + credentialDefinitionId: `TL1EaPFCZ8Si5aUrqScBDt:3:CL:${schemaResponse.schemaMetadata.indyLedgerSeqNo}:TAG`, + credentialDefinition: { + issuerId: 'TL1EaPFCZ8Si5aUrqScBDt', + // FIXME: this will change when https://github.com/hyperledger/aries-framework-javascript/issues/1259 is merged + schemaId: `${schemaResponse.schemaMetadata.indyLedgerSeqNo}`, + tag: 'TAG', + type: 'CL', + value: { + primary: { + primary: { + n: '92511867718854414868106363741369833735017762038454769060600859608405811709675033445666654908195955460485998711087020152978597220168927505650092431295783175164390266561239892662085428655566792056852960599485298025843840058914610127716620252006466964070280255168745873592143068949458568751438337748294055976926080232538440619420568859737673474560851456027625679328271511966332808025880807996449998057729417608399774744254122385012832309402226532031122728445959276178939234308090390331654445053482963947804769291501664200141562885660084823885847247231002821472258218384342423605116504024514572826071246440130942849549441', + r: { + age: '676933340341980399002624386891134393471002096508227567343731826159610079436978196421307099268754545293545727546242372579987825752872485684085629459107300175443328323289748793060894500514926703654606851666031895448970879827423190730510730624784665299646624113512701254199984520803796529034094958026048762178753193812250643294518237843809104055653333871102658177900702978008644780459400512716361564897282969982554031820285585105004870317861287847206222714589633178648982299799311192432563797220854755882933052881306804544233529886513105815543097685128456041780804442879272476590077760678785460726492895806240870944398', + master_secret: + '57770757113548032970308439965749734133430520933173186296299026579579930337912607419798836831937319372744879560676750427054135869214212225572618340088847222727882935159356459822445182287686057012197046378986248048722180093079919306125315662058290895629438767985427829790980355162853804522854494960613869765167538645624719923127052541372069255024631093663068055100579264049925388231368871107383977060590248865498902704546409806115171120555709438784189721957301548212242748685629860268468247494986146122636455769804467583612610341632602695197189514316033637331733820369170763954604394734655429769801516997967996980978751', + }, + rctxt: + '19574881057684356733946284215946569464410211018678168661028327420122678446653210056362495902735819742274128834330867933095119512313591151219353395069123546495720010325822330866859140765940839241212947354612836044244554152389691282543839111284006009168728161183863936810142428875817934316327118674532328892591410224676539770085459540786747902789677759379901079898127879301595929571621032704093287675668250862222728331030586585586110859977896767318814398026750215625180255041545607499673023585546720788973882263863911222208020438685873501025545464213035270207099419236974668665979962146355749687924650853489277747454993', + s: '80388543865249952799447792504739237616187770512259677275061283897050980768551818104137338144380636412773836688624071360386172349725818126495487584981520630638409717065318132420766896092370913800616033623618952639023946750307405126873476182540669638841562357523429245685476919178722373320218824590869735129801004394337640642997250464303104754942997839179333543643110326022824394934965538190976474473353762308333205671176627192797138375084260446324344637548455228161138089974447059481109651156379803576163576511072261388342837813901850712083922506433336723723235701670225584863772222447543742649328218950436824219992164', + z: '18569464356833363098514177097771727133940629758890641648661259687745137028161881113251218061243607037717553708179509640909238773964066423807945164288256211132195919975343578956381001087353353060599758005375631247614777454313440511375923345538396573548499287265163879524050255226779884271432737062283353279122281220812931572456820130441114446870167673796490210349453498315913599982158253821945225264065364670730546176140788405935081171854642125236557475395879246419105888077042924382595999612137336915304205628167917473420377397118829734604949103124514367857266518654728464539418834291071874052392799652266418817991437', + }, + }, + }, + }, + credentialDefinitionMetadata: { + didIndyNamespace: 'local:test', + }, + resolutionMetadata: {}, + }) + }) +}) diff --git a/packages/indy-vdr/tests/indy-vdr-pool.e2e.test.ts b/packages/indy-vdr/tests/indy-vdr-pool.e2e.test.ts index 52bd467cd5..95a3882ff1 100644 --- a/packages/indy-vdr/tests/indy-vdr-pool.e2e.test.ts +++ b/packages/indy-vdr/tests/indy-vdr-pool.e2e.test.ts @@ -1,12 +1,13 @@ import type { Key } from '@aries-framework/core' -import { IndyWallet, KeyType, SigningProviderRegistry, TypedArrayEncoder } from '@aries-framework/core' +import { IndyWallet, KeyType, SigningProviderRegistry } from '@aries-framework/core' import { GetNymRequest, NymRequest, SchemaRequest, CredentialDefinitionRequest } from '@hyperledger/indy-vdr-shared' import { agentDependencies, genesisTransactions, getAgentConfig, getAgentContext } from '../../core/tests/helpers' import testLogger from '../../core/tests/logger' import { IndyVdrPool } from '../src/pool' import { IndyVdrPoolService } from '../src/pool/IndyVdrPoolService' +import { indyDidFromPublicKeyBase58 } from '../src/utils/did' const indyVdrPoolService = new IndyVdrPoolService(testLogger) const wallet = new IndyWallet(agentDependencies, testLogger, new SigningProviderRegistry([])) @@ -88,8 +89,7 @@ describe('IndyVdrPoolService', () => { // prepare the DID we are going to write to the ledger const key = await wallet.createKey({ keyType: KeyType.Ed25519 }) - const buffer = TypedArrayEncoder.fromBase58(key.publicKeyBase58) - const did = TypedArrayEncoder.toBase58(buffer.slice(0, 16)) + const did = indyDidFromPublicKeyBase58(key.publicKeyBase58) const request = new NymRequest({ dest: did, @@ -116,108 +116,106 @@ describe('IndyVdrPoolService', () => { }) }) - describe('Schemas & credential Definition', () => { - test('can write a schema using the pool', async () => { - const pool = indyVdrPoolService.getPoolForNamespace('pool:localtest') + test('can write a schema and credential definition using the pool', async () => { + const pool = indyVdrPoolService.getPoolForNamespace('pool:localtest') - const dynamicVersion = `1.${Math.random() * 100}` + const dynamicVersion = `1.${Math.random() * 100}` - const schemaRequest = new SchemaRequest({ - submitterDid: 'TL1EaPFCZ8Si5aUrqScBDt', - schema: { - id: 'test-schema-id', - name: 'test-schema', - ver: '1.0', - version: dynamicVersion, - attrNames: ['first_name', 'last_name', 'age'], - }, - }) + const schemaRequest = new SchemaRequest({ + submitterDid: 'TL1EaPFCZ8Si5aUrqScBDt', + schema: { + id: 'test-schema-id', + name: 'test-schema', + ver: '1.0', + version: dynamicVersion, + attrNames: ['first_name', 'last_name', 'age'], + }, + }) - const schemaResponse = await pool.submitWriteRequest(agentContext, schemaRequest, signerKey) + const schemaResponse = await pool.submitWriteRequest(agentContext, schemaRequest, signerKey) - expect(schemaResponse).toMatchObject({ - op: 'REPLY', - result: { - ver: '1', - txn: { - metadata: expect.any(Object), - type: '101', + expect(schemaResponse).toMatchObject({ + op: 'REPLY', + result: { + ver: '1', + txn: { + metadata: expect.any(Object), + type: '101', + data: { data: { - data: { - attr_names: expect.arrayContaining(['age', 'last_name', 'first_name']), - name: 'test-schema', - version: dynamicVersion, - }, + attr_names: expect.arrayContaining(['age', 'last_name', 'first_name']), + name: 'test-schema', + version: dynamicVersion, }, }, }, - }) + }, + }) - const credentialDefinitionRequest = new CredentialDefinitionRequest({ - submitterDid: 'TL1EaPFCZ8Si5aUrqScBDt', - credentialDefinition: { - ver: '1.0', - id: `TL1EaPFCZ8Si5aUrqScBDt:3:CL:${schemaResponse.result.txnMetadata.seqNo}:TAG`, - // must be string version of the schema seqNo - schemaId: `${schemaResponse.result.txnMetadata.seqNo}`, - type: 'CL', - tag: 'TAG', - value: { - primary: { - n: '95671911213029889766246243339609567053285242961853979532076192834533577534909796042025401129640348836502648821408485216223269830089771714177855160978214805993386076928594836829216646288195127289421136294309746871614765411402917891972999085287429566166932354413679994469616357622976775651506242447852304853465380257226445481515631782793575184420720296120464167257703633829902427169144462981949944348928086406211627174233811365419264314148304536534528344413738913277713548403058098093453580992173145127632199215550027527631259565822872315784889212327945030315062879193999012349220118290071491899498795367403447663354833', - s: '1573939820553851804028472930351082111827449763317396231059458630252708273163050576299697385049087601314071156646675105028237105229428440185022593174121924731226634356276616495327358864865629675802738680754755949997611920669823449540027707876555408118172529688443208301403297680159171306000341239398135896274940688268460793682007115152428685521865921925309154307574955324973580144009271977076586453011938089159885164705002797196738438392179082905738155386545935208094240038135576042886730802817809757582039362798495805441520744154270346780731494125065136433163757697326955962282840631850597919384092584727207908978907', - r: { - master_secret: - '51468326064458249697956272807708948542001661888325200180968238787091473418947480867518174106588127385097619219536294589148765074804124925845579871788369264160902401097166484002617399484700234182426993061977152961670486891123188739266793651668791365808983166555735631354925174224786218771453042042304773095663181121735652667614424198057134974727791329623974680096491276337756445057223988781749506082654194307092164895251308088903000573135447235553684949564809677864522417041639512933806794232354223826262154508950271949764583849083972967642587778197779127063591201123312548182885603427440981731822883101260509710567731', - last_name: - '35864556460959997092903171610228165251001245539613587319116151716453114432309327039517115215674024166920383445379522674504803469517283236033110568676156285676664363558333716898161685255450536856645604857714925836474250821415182026707218622134953915013803750771185050002646661004119778318524426368842019753903741998256374803456282688037624993010626333853831264356355867746685055670790915539230702546586615988121383960277550317876816983602795121749533628953449405383896799464872758725899520173321672584180060465965090049734285011738428381648013150818429882628144544132356242262467090140003979917439514443707537952643217', - first_name: - '26405366527417391838431479783966663952336302347775179063968690502492620867161212873635806190080000833725932174641667734138216137047349915190546601368424742647800764149890590518336588437317392528514313749533980651547425554257026971104775208127915118918084350210726664749850578299247705298976657301433446491575776774836993110356033664644761593799921221474617858131678955318702706530853801195330271860527250931569815553226145458665481867408279941785848264018364216087471931232367137301987457054918438087686484522112532447779498424748261678616461026788516567300969886029412198319909977473167405879110243445062391837349387', - age: '19865805272519696320755573045337531955436490760876870776207490804137339344112305203631892390827288264857621916650098902064979838987400911652887344763586495880167030031364467726355103327059673023946234460960685398768709062405377107912774045508870580108596597470880834205563197111550140867466625683117333370595295321833757429488192170551320637065066368716366317421169802474954914904380304190861641082310805418122837214965865969459724848071006870574514215255412289237027267424055400593307112849859757094597401668252862525566316402695830217450073667487951799749275437192883439584518905943435472478496028380016245355151988', - }, - rctxt: - '17146114573198643698878017247599007910707723139165264508694101989891626297408755744139587708989465136799243292477223763665064840330721616213638280284119891715514951989022398510785960099708705561761504012512387129498731093386014964896897751536856287377064154297370092339714578039195258061017640952790913108285519632654466006255438773382930416822756630391947263044087385305540191237328903426888518439803354213792647775798033294505898635058814132665832000734168261793545453678083703704122695006541391598116359796491845268631009298069826949515604008666680160398698425061157356267086946953480945396595351944425658076127674', - z: '57056568014385132434061065334124327103768023932445648883765905576432733866307137325457775876741578717650388638737098805750938053855430851133826479968450532729423746605371536096355616166421996729493639634413002114547787617999178137950004782677177313856876420539744625174205603354705595789330008560775613287118432593300023801651460885523314713996258581986238928077688246511704050386525431448517516821261983193275502089060128363906909778842476516981025598807378338053788433033754999771876361716562378445777250912525673660842724168260417083076824975992327559199634032439358787956784395443246565622469187082767614421691234', + const credentialDefinitionRequest = new CredentialDefinitionRequest({ + submitterDid: 'TL1EaPFCZ8Si5aUrqScBDt', + credentialDefinition: { + ver: '1.0', + id: `TL1EaPFCZ8Si5aUrqScBDt:3:CL:${schemaResponse.result.txnMetadata.seqNo}:TAG`, + // must be string version of the schema seqNo + schemaId: `${schemaResponse.result.txnMetadata.seqNo}`, + type: 'CL', + tag: 'TAG', + value: { + primary: { + n: '95671911213029889766246243339609567053285242961853979532076192834533577534909796042025401129640348836502648821408485216223269830089771714177855160978214805993386076928594836829216646288195127289421136294309746871614765411402917891972999085287429566166932354413679994469616357622976775651506242447852304853465380257226445481515631782793575184420720296120464167257703633829902427169144462981949944348928086406211627174233811365419264314148304536534528344413738913277713548403058098093453580992173145127632199215550027527631259565822872315784889212327945030315062879193999012349220118290071491899498795367403447663354833', + s: '1573939820553851804028472930351082111827449763317396231059458630252708273163050576299697385049087601314071156646675105028237105229428440185022593174121924731226634356276616495327358864865629675802738680754755949997611920669823449540027707876555408118172529688443208301403297680159171306000341239398135896274940688268460793682007115152428685521865921925309154307574955324973580144009271977076586453011938089159885164705002797196738438392179082905738155386545935208094240038135576042886730802817809757582039362798495805441520744154270346780731494125065136433163757697326955962282840631850597919384092584727207908978907', + r: { + master_secret: + '51468326064458249697956272807708948542001661888325200180968238787091473418947480867518174106588127385097619219536294589148765074804124925845579871788369264160902401097166484002617399484700234182426993061977152961670486891123188739266793651668791365808983166555735631354925174224786218771453042042304773095663181121735652667614424198057134974727791329623974680096491276337756445057223988781749506082654194307092164895251308088903000573135447235553684949564809677864522417041639512933806794232354223826262154508950271949764583849083972967642587778197779127063591201123312548182885603427440981731822883101260509710567731', + last_name: + '35864556460959997092903171610228165251001245539613587319116151716453114432309327039517115215674024166920383445379522674504803469517283236033110568676156285676664363558333716898161685255450536856645604857714925836474250821415182026707218622134953915013803750771185050002646661004119778318524426368842019753903741998256374803456282688037624993010626333853831264356355867746685055670790915539230702546586615988121383960277550317876816983602795121749533628953449405383896799464872758725899520173321672584180060465965090049734285011738428381648013150818429882628144544132356242262467090140003979917439514443707537952643217', + first_name: + '26405366527417391838431479783966663952336302347775179063968690502492620867161212873635806190080000833725932174641667734138216137047349915190546601368424742647800764149890590518336588437317392528514313749533980651547425554257026971104775208127915118918084350210726664749850578299247705298976657301433446491575776774836993110356033664644761593799921221474617858131678955318702706530853801195330271860527250931569815553226145458665481867408279941785848264018364216087471931232367137301987457054918438087686484522112532447779498424748261678616461026788516567300969886029412198319909977473167405879110243445062391837349387', + age: '19865805272519696320755573045337531955436490760876870776207490804137339344112305203631892390827288264857621916650098902064979838987400911652887344763586495880167030031364467726355103327059673023946234460960685398768709062405377107912774045508870580108596597470880834205563197111550140867466625683117333370595295321833757429488192170551320637065066368716366317421169802474954914904380304190861641082310805418122837214965865969459724848071006870574514215255412289237027267424055400593307112849859757094597401668252862525566316402695830217450073667487951799749275437192883439584518905943435472478496028380016245355151988', }, + rctxt: + '17146114573198643698878017247599007910707723139165264508694101989891626297408755744139587708989465136799243292477223763665064840330721616213638280284119891715514951989022398510785960099708705561761504012512387129498731093386014964896897751536856287377064154297370092339714578039195258061017640952790913108285519632654466006255438773382930416822756630391947263044087385305540191237328903426888518439803354213792647775798033294505898635058814132665832000734168261793545453678083703704122695006541391598116359796491845268631009298069826949515604008666680160398698425061157356267086946953480945396595351944425658076127674', + z: '57056568014385132434061065334124327103768023932445648883765905576432733866307137325457775876741578717650388638737098805750938053855430851133826479968450532729423746605371536096355616166421996729493639634413002114547787617999178137950004782677177313856876420539744625174205603354705595789330008560775613287118432593300023801651460885523314713996258581986238928077688246511704050386525431448517516821261983193275502089060128363906909778842476516981025598807378338053788433033754999771876361716562378445777250912525673660842724168260417083076824975992327559199634032439358787956784395443246565622469187082767614421691234', }, }, - }) + }, + }) - const response = await pool.submitWriteRequest(agentContext, credentialDefinitionRequest, signerKey) + const response = await pool.submitWriteRequest(agentContext, credentialDefinitionRequest, signerKey) - expect(response).toMatchObject({ - op: 'REPLY', - result: { - ver: '1', - txn: { - metadata: expect.any(Object), - type: '102', + expect(response).toMatchObject({ + op: 'REPLY', + result: { + ver: '1', + txn: { + metadata: expect.any(Object), + type: '102', + data: { data: { - data: { - primary: { - r: { - last_name: - '35864556460959997092903171610228165251001245539613587319116151716453114432309327039517115215674024166920383445379522674504803469517283236033110568676156285676664363558333716898161685255450536856645604857714925836474250821415182026707218622134953915013803750771185050002646661004119778318524426368842019753903741998256374803456282688037624993010626333853831264356355867746685055670790915539230702546586615988121383960277550317876816983602795121749533628953449405383896799464872758725899520173321672584180060465965090049734285011738428381648013150818429882628144544132356242262467090140003979917439514443707537952643217', - first_name: - '26405366527417391838431479783966663952336302347775179063968690502492620867161212873635806190080000833725932174641667734138216137047349915190546601368424742647800764149890590518336588437317392528514313749533980651547425554257026971104775208127915118918084350210726664749850578299247705298976657301433446491575776774836993110356033664644761593799921221474617858131678955318702706530853801195330271860527250931569815553226145458665481867408279941785848264018364216087471931232367137301987457054918438087686484522112532447779498424748261678616461026788516567300969886029412198319909977473167405879110243445062391837349387', - age: '19865805272519696320755573045337531955436490760876870776207490804137339344112305203631892390827288264857621916650098902064979838987400911652887344763586495880167030031364467726355103327059673023946234460960685398768709062405377107912774045508870580108596597470880834205563197111550140867466625683117333370595295321833757429488192170551320637065066368716366317421169802474954914904380304190861641082310805418122837214965865969459724848071006870574514215255412289237027267424055400593307112849859757094597401668252862525566316402695830217450073667487951799749275437192883439584518905943435472478496028380016245355151988', - master_secret: - '51468326064458249697956272807708948542001661888325200180968238787091473418947480867518174106588127385097619219536294589148765074804124925845579871788369264160902401097166484002617399484700234182426993061977152961670486891123188739266793651668791365808983166555735631354925174224786218771453042042304773095663181121735652667614424198057134974727791329623974680096491276337756445057223988781749506082654194307092164895251308088903000573135447235553684949564809677864522417041639512933806794232354223826262154508950271949764583849083972967642587778197779127063591201123312548182885603427440981731822883101260509710567731', - }, - z: '57056568014385132434061065334124327103768023932445648883765905576432733866307137325457775876741578717650388638737098805750938053855430851133826479968450532729423746605371536096355616166421996729493639634413002114547787617999178137950004782677177313856876420539744625174205603354705595789330008560775613287118432593300023801651460885523314713996258581986238928077688246511704050386525431448517516821261983193275502089060128363906909778842476516981025598807378338053788433033754999771876361716562378445777250912525673660842724168260417083076824975992327559199634032439358787956784395443246565622469187082767614421691234', - rctxt: - '17146114573198643698878017247599007910707723139165264508694101989891626297408755744139587708989465136799243292477223763665064840330721616213638280284119891715514951989022398510785960099708705561761504012512387129498731093386014964896897751536856287377064154297370092339714578039195258061017640952790913108285519632654466006255438773382930416822756630391947263044087385305540191237328903426888518439803354213792647775798033294505898635058814132665832000734168261793545453678083703704122695006541391598116359796491845268631009298069826949515604008666680160398698425061157356267086946953480945396595351944425658076127674', - n: '95671911213029889766246243339609567053285242961853979532076192834533577534909796042025401129640348836502648821408485216223269830089771714177855160978214805993386076928594836829216646288195127289421136294309746871614765411402917891972999085287429566166932354413679994469616357622976775651506242447852304853465380257226445481515631782793575184420720296120464167257703633829902427169144462981949944348928086406211627174233811365419264314148304536534528344413738913277713548403058098093453580992173145127632199215550027527631259565822872315784889212327945030315062879193999012349220118290071491899498795367403447663354833', - s: '1573939820553851804028472930351082111827449763317396231059458630252708273163050576299697385049087601314071156646675105028237105229428440185022593174121924731226634356276616495327358864865629675802738680754755949997611920669823449540027707876555408118172529688443208301403297680159171306000341239398135896274940688268460793682007115152428685521865921925309154307574955324973580144009271977076586453011938089159885164705002797196738438392179082905738155386545935208094240038135576042886730802817809757582039362798495805441520744154270346780731494125065136433163757697326955962282840631850597919384092584727207908978907', + primary: { + r: { + last_name: + '35864556460959997092903171610228165251001245539613587319116151716453114432309327039517115215674024166920383445379522674504803469517283236033110568676156285676664363558333716898161685255450536856645604857714925836474250821415182026707218622134953915013803750771185050002646661004119778318524426368842019753903741998256374803456282688037624993010626333853831264356355867746685055670790915539230702546586615988121383960277550317876816983602795121749533628953449405383896799464872758725899520173321672584180060465965090049734285011738428381648013150818429882628144544132356242262467090140003979917439514443707537952643217', + first_name: + '26405366527417391838431479783966663952336302347775179063968690502492620867161212873635806190080000833725932174641667734138216137047349915190546601368424742647800764149890590518336588437317392528514313749533980651547425554257026971104775208127915118918084350210726664749850578299247705298976657301433446491575776774836993110356033664644761593799921221474617858131678955318702706530853801195330271860527250931569815553226145458665481867408279941785848264018364216087471931232367137301987457054918438087686484522112532447779498424748261678616461026788516567300969886029412198319909977473167405879110243445062391837349387', + age: '19865805272519696320755573045337531955436490760876870776207490804137339344112305203631892390827288264857621916650098902064979838987400911652887344763586495880167030031364467726355103327059673023946234460960685398768709062405377107912774045508870580108596597470880834205563197111550140867466625683117333370595295321833757429488192170551320637065066368716366317421169802474954914904380304190861641082310805418122837214965865969459724848071006870574514215255412289237027267424055400593307112849859757094597401668252862525566316402695830217450073667487951799749275437192883439584518905943435472478496028380016245355151988', + master_secret: + '51468326064458249697956272807708948542001661888325200180968238787091473418947480867518174106588127385097619219536294589148765074804124925845579871788369264160902401097166484002617399484700234182426993061977152961670486891123188739266793651668791365808983166555735631354925174224786218771453042042304773095663181121735652667614424198057134974727791329623974680096491276337756445057223988781749506082654194307092164895251308088903000573135447235553684949564809677864522417041639512933806794232354223826262154508950271949764583849083972967642587778197779127063591201123312548182885603427440981731822883101260509710567731', }, + z: '57056568014385132434061065334124327103768023932445648883765905576432733866307137325457775876741578717650388638737098805750938053855430851133826479968450532729423746605371536096355616166421996729493639634413002114547787617999178137950004782677177313856876420539744625174205603354705595789330008560775613287118432593300023801651460885523314713996258581986238928077688246511704050386525431448517516821261983193275502089060128363906909778842476516981025598807378338053788433033754999771876361716562378445777250912525673660842724168260417083076824975992327559199634032439358787956784395443246565622469187082767614421691234', + rctxt: + '17146114573198643698878017247599007910707723139165264508694101989891626297408755744139587708989465136799243292477223763665064840330721616213638280284119891715514951989022398510785960099708705561761504012512387129498731093386014964896897751536856287377064154297370092339714578039195258061017640952790913108285519632654466006255438773382930416822756630391947263044087385305540191237328903426888518439803354213792647775798033294505898635058814132665832000734168261793545453678083703704122695006541391598116359796491845268631009298069826949515604008666680160398698425061157356267086946953480945396595351944425658076127674', + n: '95671911213029889766246243339609567053285242961853979532076192834533577534909796042025401129640348836502648821408485216223269830089771714177855160978214805993386076928594836829216646288195127289421136294309746871614765411402917891972999085287429566166932354413679994469616357622976775651506242447852304853465380257226445481515631782793575184420720296120464167257703633829902427169144462981949944348928086406211627174233811365419264314148304536534528344413738913277713548403058098093453580992173145127632199215550027527631259565822872315784889212327945030315062879193999012349220118290071491899498795367403447663354833', + s: '1573939820553851804028472930351082111827449763317396231059458630252708273163050576299697385049087601314071156646675105028237105229428440185022593174121924731226634356276616495327358864865629675802738680754755949997611920669823449540027707876555408118172529688443208301403297680159171306000341239398135896274940688268460793682007115152428685521865921925309154307574955324973580144009271977076586453011938089159885164705002797196738438392179082905738155386545935208094240038135576042886730802817809757582039362798495805441520744154270346780731494125065136433163757697326955962282840631850597919384092584727207908978907', }, - signature_type: 'CL', - ref: schemaResponse.result.txnMetadata.seqNo, - tag: 'TAG', }, + signature_type: 'CL', + ref: schemaResponse.result.txnMetadata.seqNo, + tag: 'TAG', }, }, - }) + }, }) }) }) From 165e673aab1b0a43f10649b433b119fab3d7502d Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Thu, 9 Feb 2023 17:57:14 +0100 Subject: [PATCH 10/11] test(indy-sdk): increase timeout for slow ci Signed-off-by: Timo Glastra --- packages/indy-sdk/tests/setup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/indy-sdk/tests/setup.ts b/packages/indy-sdk/tests/setup.ts index 719a473b6e..b60b932be5 100644 --- a/packages/indy-sdk/tests/setup.ts +++ b/packages/indy-sdk/tests/setup.ts @@ -1 +1 @@ -jest.setTimeout(10000) +jest.setTimeout(25000) From 66062536166d5d7f13461229ccf72bbb33b89ab5 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Thu, 9 Feb 2023 19:10:01 +0100 Subject: [PATCH 11/11] chore: add anoncreds package Signed-off-by: Timo Glastra --- packages/indy-vdr/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/indy-vdr/package.json b/packages/indy-vdr/package.json index e12d0116de..e73cfd7a83 100644 --- a/packages/indy-vdr/package.json +++ b/packages/indy-vdr/package.json @@ -25,6 +25,7 @@ "test": "jest" }, "dependencies": { + "@aries-framework/anoncreds": "0.3.3", "@aries-framework/core": "0.3.3", "@hyperledger/indy-vdr-shared": "^0.1.0-dev.4" },