From a91ca886b06e1cbb5b2b9747751075c3c901b161 Mon Sep 17 00:00:00 2001 From: Berend Sliedrecht <berend@animo.id> Date: Tue, 30 Jan 2024 11:56:10 +0100 Subject: [PATCH] feat: added transaction endorsement Signed-off-by: Berend Sliedrecht <berend@animo.id> --- apps/shared/src/events/didEvents.ts | 15 ++ apps/ssi-abstraction/package.json | 3 +- .../src/agent/agent.service.ts | 23 ++- .../credentialDefinitions.service.ts | 46 +++++- .../src/agent/dids/dids.controller.ts | 10 ++ .../src/agent/dids/dids.service.ts | 138 ++++++++++++++---- .../agent/revocation/revocation.controller.ts | 4 +- .../agent/revocation/revocation.service.ts | 68 +++++++-- .../src/agent/schemas/schemas.service.ts | 39 ++++- .../src/agent/withTenantService.ts | 19 +-- apps/ssi-abstraction/src/app.module.ts | 4 + apps/ssi-abstraction/src/common/utils.ts | 8 + apps/ssi-abstraction/src/config/ledger.ts | 2 +- .../test/anoncredsCredentials.e2e-spec.ts | 8 +- .../test/credentialDefinitions.e2e-spec.ts | 8 +- apps/ssi-abstraction/test/dids.e2e-spec.ts | 33 ++++- apps/ssi-abstraction/test/jest.config.js | 2 +- .../test/revocation.e2e-spec.ts | 129 ++++++++++++++++ apps/ssi-abstraction/test/schemas.e2e-spec.ts | 5 +- pnpm-lock.yaml | 89 ++++++----- 20 files changed, 539 insertions(+), 114 deletions(-) create mode 100644 apps/ssi-abstraction/src/common/utils.ts create mode 100644 apps/ssi-abstraction/test/revocation.e2e-spec.ts diff --git a/apps/shared/src/events/didEvents.ts b/apps/shared/src/events/didEvents.ts index 5b39c61..fff58aa 100644 --- a/apps/shared/src/events/didEvents.ts +++ b/apps/shared/src/events/didEvents.ts @@ -17,6 +17,21 @@ export class EventDidsResolve extends BaseEvent<DidDocument> { } } +export type EventDidsRegisterEndorserDidInput = never; +export class EventDidsRegisterEndorserDid extends BaseEvent { + public static token = 'dids.register.indy.endorser'; + + public static fromEvent(e: EventDidsRegisterEndorserDid) { + return new EventDidsRegisterEndorserDid( + e.data, + e.tenantId, + e.id, + e.type, + e.timestamp, + ); + } +} + export type EventDidsRegisterIndyFromSeedInput = BaseEventInput<{ seed: string; services?: Array<{ diff --git a/apps/ssi-abstraction/package.json b/apps/ssi-abstraction/package.json index a6e86e3..95d5088 100644 --- a/apps/ssi-abstraction/package.json +++ b/apps/ssi-abstraction/package.json @@ -11,7 +11,8 @@ "prebuild": "rimraf dist", "build": "nest build -p tsconfig.production.json", "start": "nest start --watch --preserveWatchOutput", - "test": "jest" + "test": "jest", + "test:e2e": "pnpm test -- -c=test/jest.config.js --runInBand" }, "dependencies": { "@credo-ts/anoncreds": "0.5.0-alpha.116", diff --git a/apps/ssi-abstraction/src/agent/agent.service.ts b/apps/ssi-abstraction/src/agent/agent.service.ts index a0db4d9..315eef3 100644 --- a/apps/ssi-abstraction/src/agent/agent.service.ts +++ b/apps/ssi-abstraction/src/agent/agent.service.ts @@ -45,6 +45,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { logger } from '@ocm/shared'; +import { parseDid } from '../common/utils.js'; import { LEDGERS } from '../config/ledger.js'; import { AgentLogger } from './logger.js'; @@ -182,6 +183,27 @@ export class AgentService implements OnApplicationShutdown { }); } + public async getEndorserDid(issuerDid: string) { + const { method, namespaceAndNetwork } = parseDid(issuerDid); + const dids = await this.agent.dids.getCreatedDids({ method }); + + const did = dids + .map(({ did }) => did) + .find((did) => did.includes(namespaceAndNetwork)); + + if (!did) { + throw new Error( + `Could not find endorser did for method: '${method}' on network: '${namespaceAndNetwork}'`, + ); + } + + return did; + } + + public async endorseTransaction(txn: string, endorserDid: string) { + return this.agent.modules.indyVdr.endorseTransaction(txn, endorserDid); + } + public async onModuleInit() { await this.agent.initialize(); logger.info('Agent initialized'); @@ -194,7 +216,6 @@ export class AgentService implements OnApplicationShutdown { // This is done because the Askar shutdown procedure is a bit buggy try { await this.agent.shutdown(); - // eslint-disable-next-line no-empty } catch (e) { logger.warn(`Agent shutdown issue occurred. Cause: ${e}`); } diff --git a/apps/ssi-abstraction/src/agent/credentialDefinitions/credentialDefinitions.service.ts b/apps/ssi-abstraction/src/agent/credentialDefinitions/credentialDefinitions.service.ts index ac212a4..e80c188 100644 --- a/apps/ssi-abstraction/src/agent/credentialDefinitions/credentialDefinitions.service.ts +++ b/apps/ssi-abstraction/src/agent/credentialDefinitions/credentialDefinitions.service.ts @@ -10,11 +10,15 @@ import type { import { Injectable } from '@nestjs/common'; +import { AgentService } from '../agent.service.js'; import { WithTenantService } from '../withTenantService.js'; @Injectable() export class CredentialDefinitionsService { - public constructor(private withTenantService: WithTenantService) {} + public constructor( + private withTenantService: WithTenantService, + private agentService: AgentService, + ) {} public async getAll({ tenantId, @@ -57,6 +61,7 @@ export class CredentialDefinitionsService { }: EventAnonCredsCredentialDefinitionsRegisterInput): Promise< EventAnonCredsCredentialDefinitionsRegister['data'] > { + const endorserDid = await this.agentService.getEndorserDid(issuerDid); return this.withTenantService.invoke(tenantId, async (t) => { const { credentialDefinitionState } = await t.modules.anoncreds.registerCredentialDefinition<IndyVdrRegisterCredentialDefinitionOptions>( @@ -67,14 +72,17 @@ export class CredentialDefinitionsService { tag, }, options: { - endorserMode: 'internal', - endorserDid: issuerDid, + endorserMode: 'external', + endorserDid, supportRevocation: supportsRevocation, }, }, ); - if (credentialDefinitionState.state !== 'finished') { + if ( + credentialDefinitionState.state !== 'action' || + credentialDefinitionState.action !== 'endorseIndyTransaction' + ) { throw new Error( `Error registering credentialDefinition: ${ credentialDefinitionState.state === 'failed' @@ -84,6 +92,36 @@ export class CredentialDefinitionsService { ); } + const signedcredentialDefinitionRequest = + await this.agentService.endorseTransaction( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + credentialDefinitionState.credentialDefinitionRequest, + endorserDid, + ); + + const credentialDefinitionSubmitResult = + await t.modules.anoncreds.registerCredentialDefinition<IndyVdrRegisterCredentialDefinitionOptions>( + { + options: { + endorsedTransaction: signedcredentialDefinitionRequest, + endorserMode: 'external', + supportRevocation: supportsRevocation, + }, + credentialDefinition: + credentialDefinitionState.credentialDefinition, + }, + ); + + if ( + credentialDefinitionSubmitResult.credentialDefinitionState.state !== + 'finished' + ) { + throw Error( + `Error while registering credentialDefinition. Cause: ${JSON.stringify(credentialDefinitionSubmitResult)}`, + ); + } + return { credentialDefinitionId: credentialDefinitionState.credentialDefinitionId, diff --git a/apps/ssi-abstraction/src/agent/dids/dids.controller.ts b/apps/ssi-abstraction/src/agent/dids/dids.controller.ts index 2556483..de2f26e 100644 --- a/apps/ssi-abstraction/src/agent/dids/dids.controller.ts +++ b/apps/ssi-abstraction/src/agent/dids/dids.controller.ts @@ -3,6 +3,8 @@ import { MessagePattern } from '@nestjs/microservices'; import { EventDidsDidConfiguration, EventDidsDidConfigurationInput, + EventDidsRegisterEndorserDid, + EventDidsRegisterEndorserDidInput, EventDidsRegisterIndyFromSeed, EventDidsRegisterIndyFromSeedInput, EventDidsResolve, @@ -23,6 +25,14 @@ export class DidsController { ); } + @MessagePattern(EventDidsRegisterEndorserDid.token) + public async registerEndorserDid(options: EventDidsRegisterEndorserDidInput) { + return new EventDidsRegisterEndorserDid( + await this.didsService.registerEndorserDids(options), + options.tenantId, + ); + } + @MessagePattern(EventDidsDidConfiguration.token) public async getDidConfiguration(options: EventDidsDidConfigurationInput) { return new EventDidsDidConfiguration( diff --git a/apps/ssi-abstraction/src/agent/dids/dids.service.ts b/apps/ssi-abstraction/src/agent/dids/dids.service.ts index 7a2cb50..a1888d5 100644 --- a/apps/ssi-abstraction/src/agent/dids/dids.service.ts +++ b/apps/ssi-abstraction/src/agent/dids/dids.service.ts @@ -1,4 +1,3 @@ -import type { LEDGERS } from '../../config/ledger.js'; import type { IndyVdrDidCreateOptions, IndyVdrDidCreateResult, @@ -11,6 +10,8 @@ import type { EventDidsRegisterIndyFromSeed, EventDidsResolve, EventDidsResolveInput, + EventDidsRegisterEndorserDidInput, + EventDidsRegisterEndorserDid, } from '@ocm/shared'; import { @@ -26,12 +27,15 @@ import { import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; +import { LEDGERS } from '../../config/ledger.js'; +import { AgentService } from '../agent.service.js'; import { registerPublicDids } from '../ledger/register.js'; import { WithTenantService } from '../withTenantService.js'; @Injectable() export class DidsService { public constructor( + private agentService: AgentService, private withTenantService: WithTenantService, private configService: ConfigService, ) {} @@ -66,12 +70,10 @@ export class DidsService { EventDidsDidConfiguration['data'] > { return this.withTenantService.invoke(tenantId, async (t) => { - const indyDids = t.dids.getCreatedDids({ method: 'indy' }); - const sovDids = t.dids.getCreatedDids({ method: 'sov' }); - const webDids = t.dids.getCreatedDids({ method: 'web' }); - const dids = (await Promise.all([indyDids, sovDids, webDids])).flatMap( - (d) => d, - ); + const indyDids = await t.dids.getCreatedDids({ method: 'indy' }); + const sovDids = await t.dids.getCreatedDids({ method: 'sov' }); + const webDids = await t.dids.getCreatedDids({ method: 'web' }); + const dids = [...indyDids, ...sovDids, ...webDids]; const jwtEntries: DidConfiguration['entries'] = []; const jwsService = t.dependencyManager.resolve(JwsService); @@ -115,15 +117,10 @@ export class DidsService { }); } - public async registerDidIndyFromSeed({ - tenantId, - seed, - services, - }: EventDidsRegisterIndyFromSeedInput): Promise< - EventDidsRegisterIndyFromSeed['data'] - > { - const dids: Array<string> = []; - + public async registerEndorserDids( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _?: EventDidsRegisterEndorserDidInput, + ): Promise<EventDidsRegisterEndorserDid['data']> { const ledgerIds = this.configService.get('agent.ledgerIds') as Array< keyof typeof LEDGERS >; @@ -137,6 +134,32 @@ export class DidsService { seed: publicDidSeed, }); + const privKey = { + privateKey: TypedArrayEncoder.fromString(publicDidSeed), + keyType: KeyType.Ed25519, + }; + + await this.agentService.agent.wallet.createKey(privKey); + + for (const publicDid of publicDids) { + await this.agentService.agent.dids.import({ + did: publicDid.did, + privateKeys: [privKey], + }); + } + + return {}; + } + + public async registerDidIndyFromSeed({ + tenantId, + seed, + services, + }: EventDidsRegisterIndyFromSeedInput): Promise< + EventDidsRegisterIndyFromSeed['data'] + > { + const dids: Array<string> = []; + const { publicKey, publicKeyBase58 } = await this.withTenantService.invoke( tenantId, async (t) => @@ -146,19 +169,32 @@ export class DidsService { }), ); - await this.withTenantService.invoke(tenantId, async (t) => - t.wallet.createKey({ - privateKey: TypedArrayEncoder.fromString(publicDidSeed), - keyType: KeyType.Ed25519, - }), - ); - const buffer = Hasher.hash(publicKey, 'sha2-256'); const id = TypedArrayEncoder.toBase58(buffer.slice(0, 16)); const verkey = publicKeyBase58; - for (const publicDid of publicDids) { - const did = `did:indy:${publicDid.namespace}:${id}`; + const ledgerIds = this.configService.get('agent.ledgerIds') as Array< + keyof typeof LEDGERS + >; + + for (const ledgerId of ledgerIds) { + const ledger = LEDGERS[ledgerId as keyof typeof LEDGERS]; + + const endorserDids = await this.agentService.agent.dids.getCreatedDids({ + method: 'indy', + }); + + const endorserDid = endorserDids + .map(({ did }) => did) + .find((did) => did.includes(ledger.namespace)); + + if (!endorserDid) { + throw new Error( + `Endorser did could not be found for ${ledger.namespace}`, + ); + } + + const did = `did:indy:${ledger.namespace}:${id}`; const didDocumentServices: Array<DidDocumentService> | undefined = services?.map( (s) => @@ -170,24 +206,64 @@ export class DidsService { ); await this.withTenantService.invoke(tenantId, async (t) => { - const result = (await t.dids.create<IndyVdrDidCreateOptions>({ + const { didState } = (await t.dids.create<IndyVdrDidCreateOptions>({ did, options: { verkey, - endorserMode: 'internal', - endorserDid: publicDid.did, + endorserMode: 'external', + endorserDid, services: didDocumentServices, useEndpointAttrib: true, }, })) as IndyVdrDidCreateResult; - if (result.didState.state !== 'finished') { + if ( + didState.state !== 'action' || + didState.action !== 'endorseIndyTransaction' + ) { throw Error( - `An error occurred while trying to register the did: '${did}'. Result: ${JSON.stringify(result)}`, + `An error occurred while trying to register the did: '${did}'. Result: ${JSON.stringify(didState)}`, + ); + } + + const signedNymRequest = await this.agentService.endorseTransaction( + didState.nymRequest, + didState.endorserDid, + ); + + const didCreateSubmitResult = + await t.dids.create<IndyVdrDidCreateOptions>({ + did: didState.did, + options: { + endorserMode: 'external', + endorsedTransaction: { + nymRequest: signedNymRequest, + }, + }, + secret: didState.secret, + }); + + if (didCreateSubmitResult.didState.state !== 'finished') { + throw new Error( + didCreateSubmitResult.didState.state === 'failed' + ? `Did registration for network ${ledger.namespace} failed due to '${didCreateSubmitResult.didState.reason}'` + : `Did registration for network ${ledger.namespace} failed with state '${didCreateSubmitResult.didState.state}' due to an unknown reason`, ); } - dids.push(result.didState.did); + await t.dids.import({ + did: didState.did, + didDocument: didState.didDocument, + overwrite: true, + privateKeys: [ + { + keyType: KeyType.Ed25519, + privateKey: TypedArrayEncoder.fromString(seed), + }, + ], + }); + + dids.push(didState.did); }); } diff --git a/apps/ssi-abstraction/src/agent/revocation/revocation.controller.ts b/apps/ssi-abstraction/src/agent/revocation/revocation.controller.ts index 87c1624..8267524 100644 --- a/apps/ssi-abstraction/src/agent/revocation/revocation.controller.ts +++ b/apps/ssi-abstraction/src/agent/revocation/revocation.controller.ts @@ -39,9 +39,7 @@ export class RevocationController { ); } - @MessagePattern( - EventAnonCredsRevocationRegisterRevocationRegistryDefinition.token, - ) + @MessagePattern(EventAnonCredsRevocationRegisterRevocationStatusList.token) public async registerRevocationStatusList( options: EventAnonCredsRevocationRegisterRevocationStatusListInput, ): Promise<EventAnonCredsRevocationRegisterRevocationStatusList> { diff --git a/apps/ssi-abstraction/src/agent/revocation/revocation.service.ts b/apps/ssi-abstraction/src/agent/revocation/revocation.service.ts index df4dedf..8ecff40 100644 --- a/apps/ssi-abstraction/src/agent/revocation/revocation.service.ts +++ b/apps/ssi-abstraction/src/agent/revocation/revocation.service.ts @@ -9,6 +9,7 @@ import type { import { Injectable } from '@nestjs/common'; +import { AgentService } from '../agent.service.js'; import { WithTenantService } from '../withTenantService.js'; export interface AnonCredsCredentialMetadata { @@ -20,7 +21,10 @@ export interface AnonCredsCredentialMetadata { @Injectable() export class RevocationService { - public constructor(private withTenantService: WithTenantService) {} + public constructor( + private withTenantService: WithTenantService, + private agentService: AgentService, + ) {} // Get the credential from storage // Get the revocation registry definition id @@ -111,10 +115,14 @@ export class RevocationService { }: EventAnonCredsRevocationRegisterRevocationRegistryDefinitionInput): Promise< EventAnonCredsRevocationRegisterRevocationRegistryDefinition['data'] > { + const endorserDid = await this.agentService.getEndorserDid(issuerDid); return this.withTenantService.invoke(tenantId, async (t) => { - const result = + const { revocationRegistryDefinitionState } = await t.modules.anoncreds.registerRevocationRegistryDefinition({ - options: {}, + options: { + endorserMode: 'external', + endorserDid, + }, revocationRegistryDefinition: { maximumCredentialNumber, credentialDefinitionId, @@ -123,18 +131,60 @@ export class RevocationService { }, }); - if (result.revocationRegistryDefinitionState.state !== 'finished') { + if ( + revocationRegistryDefinitionState.state !== 'action' || + revocationRegistryDefinitionState.action !== 'endorseIndyTransaction' + ) { throw new Error( - `Error registering the revocation registry definition. Error: ${JSON.stringify( - result, - )}`, + `Error registering revocation registry definition: ${ + revocationRegistryDefinitionState.state === 'failed' + ? revocationRegistryDefinitionState.reason + : 'Not Finished' + }`, + ); + } + + const signedRevocationRegistryDefinitionRequest = + await this.agentService.endorseTransaction( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + revocationRegistryDefinitionState.revocationRegistryDefinitionRequest, + endorserDid, + ); + + const revocationRegisryDefinitionSubmitResult = + await t.modules.anoncreds.registerRevocationRegistryDefinition({ + options: { + endorsedTransaction: signedRevocationRegistryDefinitionRequest, + endorserMode: 'external', + }, + revocationRegistryDefinition: { + maximumCredentialNumber: + revocationRegistryDefinitionState.revocationRegistryDefinition + .value.maxCredNum, + credentialDefinitionId: + revocationRegistryDefinitionState.revocationRegistryDefinition + .credDefId, + tag: revocationRegistryDefinitionState.revocationRegistryDefinition + .tag, + issuerId: + revocationRegistryDefinitionState.revocationRegistryDefinition + .issuerId, + }, + }); + + if ( + revocationRegisryDefinitionSubmitResult + .revocationRegistryDefinitionState.state !== 'finished' + ) { + throw Error( + `Error while registering revocation registry definition Cause: ${JSON.stringify(revocationRegisryDefinitionSubmitResult)}`, ); } return { revocationRegistryDefinitionId: - result.revocationRegistryDefinitionState - .revocationRegistryDefinitionId, + revocationRegistryDefinitionState.revocationRegistryDefinitionId, }; }); } diff --git a/apps/ssi-abstraction/src/agent/schemas/schemas.service.ts b/apps/ssi-abstraction/src/agent/schemas/schemas.service.ts index 135f28c..2bca51a 100644 --- a/apps/ssi-abstraction/src/agent/schemas/schemas.service.ts +++ b/apps/ssi-abstraction/src/agent/schemas/schemas.service.ts @@ -11,11 +11,15 @@ import type { import { Injectable } from '@nestjs/common'; +import { AgentService } from '../agent.service.js'; import { WithTenantService } from '../withTenantService.js'; @Injectable() export class SchemasService { - public constructor(private withTenantService: WithTenantService) {} + public constructor( + private withTenantService: WithTenantService, + private agentService: AgentService, + ) {} public async getAll({ tenantId, @@ -49,6 +53,8 @@ export class SchemasService { EventAnonCredsSchemasRegister['data'] > { return this.withTenantService.invoke(tenantId, async (t) => { + const endorserDid = await this.agentService.getEndorserDid(issuerDid); + const { schemaState } = await t.modules.anoncreds.registerSchema<IndyVdrRegisterSchemaOptions>({ schema: { @@ -58,12 +64,15 @@ export class SchemasService { attrNames: attributeNames, }, options: { - endorserMode: 'internal', - endorserDid: issuerDid, + endorserMode: 'external', + endorserDid, }, }); - if (schemaState.state !== 'finished' && schemaState.state !== 'action') { + if ( + schemaState.state !== 'action' || + schemaState.action !== 'endorseIndyTransaction' + ) { throw new Error( `Error registering schema: ${ schemaState.state === 'failed' ? schemaState.reason : 'Not Finished' @@ -71,6 +80,28 @@ export class SchemasService { ); } + const signedschemaRequest = await this.agentService.endorseTransaction( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + schemaState.schemaRequest, + endorserDid, + ); + + const schemaSubmitResult = + await t.modules.anoncreds.registerSchema<IndyVdrRegisterSchemaOptions>({ + options: { + endorsedTransaction: signedschemaRequest, + endorserMode: 'external', + }, + schema: schemaState.schema, + }); + + if (schemaSubmitResult.schemaState.state !== 'finished') { + throw Error( + `Error while registering schema. Cause: ${JSON.stringify(schemaSubmitResult)}`, + ); + } + return { schemaId: schemaState.schemaId, ...schemaState.schema }; }); } diff --git a/apps/ssi-abstraction/src/agent/withTenantService.ts b/apps/ssi-abstraction/src/agent/withTenantService.ts index 15b806a..7a7d565 100644 --- a/apps/ssi-abstraction/src/agent/withTenantService.ts +++ b/apps/ssi-abstraction/src/agent/withTenantService.ts @@ -12,23 +12,14 @@ export class WithTenantService { this.agent = agentService.agent; } - public invoke<T>( + public async invoke<T>( tenantId: string, cb: (tenant: TenantAgent) => Promise<T>, ): Promise<T> { - // eslint-disable-next-line no-async-promise-executor - return new Promise<T>(async (resolve, reject) => { - await this.agent.modules.tenants.withTenantAgent( - { tenantId }, - async (tenant) => { - try { - const ret = await cb(tenant as unknown as TenantAgent); - resolve(ret); - } catch (e) { - reject(e); - } - }, - ); + const tenant = await this.agent.modules.tenants.getTenantAgent({ + tenantId, }); + + return cb(tenant as unknown as TenantAgent); } } diff --git a/apps/ssi-abstraction/src/app.module.ts b/apps/ssi-abstraction/src/app.module.ts index 0ff88a6..0f1a47d 100644 --- a/apps/ssi-abstraction/src/app.module.ts +++ b/apps/ssi-abstraction/src/app.module.ts @@ -6,8 +6,10 @@ import { HealthController } from '@ocm/shared'; import { AgentModule } from './agent/agent.module.js'; import { AnonCredsCredentialsModule } from './agent/anoncredsCredentials/anoncredsCredentials.module.js'; +import { AnonCredsProofsModule } from './agent/anoncredsProofs/anoncredsProofs.module.js'; import { ConnectionsModule } from './agent/connections/connections.module.js'; import { CredentialDefinitionsModule } from './agent/credentialDefinitions/credentialDefinitions.module.js'; +import { RevocationModule } from './agent/revocation/revocation.module.js'; import { SchemasModule } from './agent/schemas/schemas.module.js'; import { TenantsModule } from './agent/tenants/tenants.module.js'; import { config } from './config/config.js'; @@ -28,7 +30,9 @@ import { validationSchema } from './config/validation.js'; DidsModule, SchemasModule, AnonCredsCredentialsModule, + AnonCredsProofsModule, TenantsModule, + RevocationModule, ], controllers: [HealthController], }) diff --git a/apps/ssi-abstraction/src/common/utils.ts b/apps/ssi-abstraction/src/common/utils.ts new file mode 100644 index 0000000..b47ebbe --- /dev/null +++ b/apps/ssi-abstraction/src/common/utils.ts @@ -0,0 +1,8 @@ +export const parseDid = (did: string) => { + const [, method, ...namespaceAndNetwork] = did.split(':'); + + return { + method, + namespaceAndNetwork: namespaceAndNetwork.slice(0, -1).join(':'), + }; +}; diff --git a/apps/ssi-abstraction/src/config/ledger.ts b/apps/ssi-abstraction/src/config/ledger.ts index eea8e8c..c23776d 100644 --- a/apps/ssi-abstraction/src/config/ledger.ts +++ b/apps/ssi-abstraction/src/config/ledger.ts @@ -28,6 +28,6 @@ export const LEDGERS = { {"reqSignature":{},"txn":{"data":{"data":{"alias":"Node3","blskey":"3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5","blskey_pop":"QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh","client_ip":"138.197.161.221","client_port":9706,"node_ip":"138.197.161.221","node_port":9705,"services":["VALIDATOR"]},"dest":"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya"},"metadata":{"from":"4cU41vWW82ArfxJxHkzXPG"},"type":"0"},"txnMetadata":{"seqNo":3,"txnId":"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4"},"ver":"1"} {"reqSignature":{},"txn":{"data":{"data":{"alias":"Node4","blskey":"2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw","blskey_pop":"RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP","client_ip":"138.197.161.221","client_port":9708,"node_ip":"138.197.161.221","node_port":9707,"services":["VALIDATOR"]},"dest":"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA"},"metadata":{"from":"TWwCRQRZ2ZHMJFn9TzLp7W"},"type":"0"},"txnMetadata":{"seqNo":4,"txnId":"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008"},"ver":"1"}`, }, -} as const; +}; export type LedgerIds = keyof typeof LEDGERS; diff --git a/apps/ssi-abstraction/test/anoncredsCredentials.e2e-spec.ts b/apps/ssi-abstraction/test/anoncredsCredentials.e2e-spec.ts index 0a9a071..672778b 100644 --- a/apps/ssi-abstraction/test/anoncredsCredentials.e2e-spec.ts +++ b/apps/ssi-abstraction/test/anoncredsCredentials.e2e-spec.ts @@ -25,6 +25,7 @@ import { EventAnonCredsProofsDeleteById, EventDidcommAnonCredsCredentialsOfferToSelf, } from '@ocm/shared'; +import { randomBytes } from 'crypto'; import { firstValueFrom } from 'rxjs'; import { AgentModule } from '../src/agent/agent.module.js'; @@ -82,10 +83,11 @@ describe('Credentials', () => { const connectionsService = app.get(ConnectionsService); await connectionsService.createConnectionWithSelf({ tenantId }); - const didsService = app.get(DidsService); - const [did] = await didsService.registerDidIndyFromSeed({ + const ds = app.get(DidsService); + await ds.registerEndorserDids(); + const [did] = await ds.registerDidIndyFromSeed({ tenantId, - seed: '12312367897123300000000000000000', + seed: randomBytes(16).toString('hex'), }); issuerDid = did; diff --git a/apps/ssi-abstraction/test/credentialDefinitions.e2e-spec.ts b/apps/ssi-abstraction/test/credentialDefinitions.e2e-spec.ts index 2fd3591..5e95231 100644 --- a/apps/ssi-abstraction/test/credentialDefinitions.e2e-spec.ts +++ b/apps/ssi-abstraction/test/credentialDefinitions.e2e-spec.ts @@ -13,6 +13,7 @@ import { EventAnonCredsCredentialDefinitionsGetAll, EventAnonCredsCredentialDefinitionsRegister, } from '@ocm/shared'; +import { randomBytes } from 'crypto'; import { firstValueFrom } from 'rxjs'; import { AgentModule } from '../src/agent/agent.module.js'; @@ -61,10 +62,11 @@ describe('CredentialDefinitions', () => { const { id } = await tenantsService.create({ label: TOKEN }); tenantId = id; - const didsService = app.get(DidsService); - const [did] = await didsService.registerDidIndyFromSeed({ + const ds = app.get(DidsService); + await ds.registerEndorserDids(); + const [did] = await ds.registerDidIndyFromSeed({ tenantId, - seed: '12312367897123300000000000000000', + seed: randomBytes(16).toString('hex'), }); issuerDid = did; diff --git a/apps/ssi-abstraction/test/dids.e2e-spec.ts b/apps/ssi-abstraction/test/dids.e2e-spec.ts index 785a8e7..1d0750a 100644 --- a/apps/ssi-abstraction/test/dids.e2e-spec.ts +++ b/apps/ssi-abstraction/test/dids.e2e-spec.ts @@ -2,6 +2,7 @@ import type { INestApplication } from '@nestjs/common'; import type { ClientProxy } from '@nestjs/microservices'; import type { EventDidsDidConfigurationInput, + EventDidsRegisterEndorserDidInput, EventDidsRegisterIndyFromSeedInput, EventDidsResolveInput, } from '@ocm/shared'; @@ -10,6 +11,7 @@ import { ClientsModule, Transport } from '@nestjs/microservices'; import { Test } from '@nestjs/testing'; import { EventDidsDidConfiguration, + EventDidsRegisterEndorserDid, EventDidsRegisterIndyFromSeed, EventDidsResolve, } from '@ocm/shared'; @@ -59,6 +61,18 @@ describe('Dids', () => { client.close(); }); + it(EventDidsRegisterEndorserDid.token, async () => { + const response$ = client.send< + EventDidsRegisterEndorserDid, + EventDidsRegisterEndorserDidInput + >(EventDidsRegisterEndorserDid.token, { tenantId }); + + const response = await firstValueFrom(response$); + const eventInstance = EventDidsRegisterEndorserDid.fromEvent(response); + + expect(eventInstance.data).toMatchObject({}); + }); + it(EventDidsRegisterIndyFromSeed.token, async () => { const response$ = client.send< EventDidsRegisterIndyFromSeed, @@ -84,6 +98,23 @@ describe('Dids', () => { }); it(EventDidsDidConfiguration.token, async () => { + const registerIndyDidResponse$ = client.send< + EventDidsRegisterIndyFromSeed, + EventDidsRegisterIndyFromSeedInput + >(EventDidsRegisterIndyFromSeed.token, { + seed: randomBytes(16).toString('hex'), + tenantId, + services: [ + { + url: 'https://example.org', + type: 'endpoint', + identifier: 'endpoint', + }, + ], + }); + + await firstValueFrom(registerIndyDidResponse$); + const response$ = client.send< EventDidsDidConfiguration, EventDidsDidConfigurationInput @@ -99,7 +130,7 @@ describe('Dids', () => { expect(eventInstance.instance).toMatchObject({ entries: expect.arrayContaining([ expect.objectContaining({ - did: 'did:indy:bcovrin:test:9MMeff63VnCpogD2FWfKnJ', + did: expect.any(String), jwt: expect.any(String), }), ]), diff --git a/apps/ssi-abstraction/test/jest.config.js b/apps/ssi-abstraction/test/jest.config.js index a166038..11a9deb 100644 --- a/apps/ssi-abstraction/test/jest.config.js +++ b/apps/ssi-abstraction/test/jest.config.js @@ -3,7 +3,7 @@ import config from '../jest.config.js'; /** @type {import('jest').Config} */ export default { ...config, - testTimeout: 42000, + testTimeout: 60000, rootDir: '.', testRegex: '.*\\.e2e-spec\\.ts$', }; diff --git a/apps/ssi-abstraction/test/revocation.e2e-spec.ts b/apps/ssi-abstraction/test/revocation.e2e-spec.ts new file mode 100644 index 0000000..83b1767 --- /dev/null +++ b/apps/ssi-abstraction/test/revocation.e2e-spec.ts @@ -0,0 +1,129 @@ +import type { INestApplication } from '@nestjs/common'; +import type { ClientProxy } from '@nestjs/microservices'; +import type { EventAnonCredsRevocationRegisterRevocationRegistryDefinitionInput } from '@ocm/shared'; + +import { ClientsModule, Transport } from '@nestjs/microservices'; +import { Test } from '@nestjs/testing'; +import { EventAnonCredsRevocationRegisterRevocationRegistryDefinition } from '@ocm/shared'; +import { randomBytes } from 'crypto'; +import { firstValueFrom } from 'rxjs'; + +import { AgentModule } from '../src/agent/agent.module.js'; +import { AnonCredsCredentialsModule } from '../src/agent/anoncredsCredentials/anoncredsCredentials.module.js'; +import { ConnectionsModule } from '../src/agent/connections/connections.module.js'; +import { ConnectionsService } from '../src/agent/connections/connections.service.js'; +import { CredentialDefinitionsModule } from '../src/agent/credentialDefinitions/credentialDefinitions.module.js'; +import { CredentialDefinitionsService } from '../src/agent/credentialDefinitions/credentialDefinitions.service.js'; +import { DidsModule } from '../src/agent/dids/dids.module.js'; +import { DidsService } from '../src/agent/dids/dids.service.js'; +import { RevocationModule } from '../src/agent/revocation/revocation.module.js'; +import { SchemasModule } from '../src/agent/schemas/schemas.module.js'; +import { SchemasService } from '../src/agent/schemas/schemas.service.js'; +import { TenantsModule } from '../src/agent/tenants/tenants.module.js'; +import { TenantsService } from '../src/agent/tenants/tenants.service.js'; +import { mockConfigModule } from '../src/config/__tests__/mockConfig.js'; + +describe('Revocation', () => { + const TOKEN = 'REVOCATION_CLIENT_SERVICE'; + let app: INestApplication; + let client: ClientProxy; + let tenantId: string; + + let issuerDid: string; + let credentialDefinitionId: string; + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + imports: [ + mockConfigModule(3004, true), + AgentModule, + ConnectionsModule, + SchemasModule, + CredentialDefinitionsModule, + AnonCredsCredentialsModule, + TenantsModule, + DidsModule, + RevocationModule, + ClientsModule.register([{ name: TOKEN, transport: Transport.NATS }]), + ], + }).compile(); + + app = moduleRef.createNestApplication(); + + app.connectMicroservice({ transport: Transport.NATS }); + + await app.startAllMicroservices(); + await app.init(); + + client = app.get(TOKEN); + await client.connect(); + + const tenantsService = app.get(TenantsService); + const { id } = await tenantsService.create({ label: TOKEN }); + tenantId = id; + + const connectionsService = app.get(ConnectionsService); + await connectionsService.createConnectionWithSelf({ tenantId }); + + const ds = app.get(DidsService); + await ds.registerEndorserDids(); + const [did] = await ds.registerDidIndyFromSeed({ + tenantId, + seed: randomBytes(16).toString('hex'), + }); + issuerDid = did; + + const schemaService = app.get(SchemasService); + const { schemaId } = await schemaService.register({ + issuerDid, + tenantId, + name: 'test-schema-name', + version: `1.${Date.now()}`, + attributeNames: ['Name', 'Age'], + }); + + const credentialDefinitionService = app.get(CredentialDefinitionsService); + const { credentialDefinitionId: cdi } = + await credentialDefinitionService.register({ + supportsRevocation: true, + tenantId, + issuerDid, + schemaId, + tag: `default-${Date.now()}`, + }); + + credentialDefinitionId = cdi; + }); + + afterAll(async () => { + await app.close(); + client.close(); + }); + + it( + EventAnonCredsRevocationRegisterRevocationRegistryDefinition.token, + async () => { + const response$ = client.send< + EventAnonCredsRevocationRegisterRevocationRegistryDefinition, + EventAnonCredsRevocationRegisterRevocationRegistryDefinitionInput + >(EventAnonCredsRevocationRegisterRevocationRegistryDefinition.token, { + tenantId, + tag: 'rev-tag', + issuerDid, + credentialDefinitionId, + maximumCredentialNumber: 100, + }); + const response = await firstValueFrom(response$); + const eventInstance = + EventAnonCredsRevocationRegisterRevocationRegistryDefinition.fromEvent( + response, + ); + + expect( + eventInstance.instance.revocationRegistryDefinitionId.startsWith( + 'did:indy:bcorvin:test:', + ), + ).toBeTruthy(); + }, + ); +}); diff --git a/apps/ssi-abstraction/test/schemas.e2e-spec.ts b/apps/ssi-abstraction/test/schemas.e2e-spec.ts index abab76b..37c4805 100644 --- a/apps/ssi-abstraction/test/schemas.e2e-spec.ts +++ b/apps/ssi-abstraction/test/schemas.e2e-spec.ts @@ -13,6 +13,7 @@ import { EventAnonCredsSchemasGetById, EventAnonCredsSchemasRegister, } from '@ocm/shared'; +import { randomBytes } from 'crypto'; import { firstValueFrom } from 'rxjs'; import { AgentModule } from '../src/agent/agent.module.js'; @@ -57,9 +58,11 @@ describe('Schemas', () => { tenantId = id; const ds = app.get(DidsService); + + await ds.registerEndorserDids(); const [did] = await ds.registerDidIndyFromSeed({ tenantId, - seed: '12312367897123300000000000000000', + seed: randomBytes(16).toString('hex'), }); issuerDid = did; }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f08918a..d7a16be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -447,12 +447,13 @@ importers: version: 0.5.0-alpha.116(expo@49.0.21)(react-native@0.73.2) ======= '@aries-framework/anoncreds': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@aries-framework/core': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@aries-framework/tenants': +<<<<<<< HEAD <<<<<<< HEAD specifier: ^0.5.0-alpha.87 version: 0.5.0-alpha.91(expo@49.0.21)(react-native@0.73.2) @@ -461,6 +462,10 @@ importers: specifier: 0.5.0-alpha.87 version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) >>>>>>> 63efb70 (fix: resolved merge issues) +======= + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) +>>>>>>> 7db39fe (feat: added transaction endorsement) '@elastic/ecs-winston-format': specifier: ^1.5.0 version: 1.5.2 @@ -564,24 +569,25 @@ importers: version: 0.5.0-alpha.116(expo@49.0.21)(react-native@0.73.2) ======= '@aries-framework/anoncreds': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@aries-framework/anoncreds-rs': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(@hyperledger/anoncreds-shared@0.2.0-dev.8)(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(@hyperledger/anoncreds-shared@0.2.0-dev.8)(expo@49.0.21)(react-native@0.73.2) '@aries-framework/askar': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(@hyperledger/aries-askar-shared@0.2.0-dev.5)(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(@hyperledger/aries-askar-shared@0.2.0-dev.5)(expo@49.0.21)(react-native@0.73.2) '@aries-framework/core': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@aries-framework/indy-vdr': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(@hyperledger/indy-vdr-shared@0.2.0-dev.6)(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(@hyperledger/indy-vdr-shared@0.2.0-dev.6)(expo@49.0.21)(react-native@0.73.2) '@aries-framework/node': - specifier: 0.5.0-alpha.87 - version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@aries-framework/tenants': +<<<<<<< HEAD <<<<<<< HEAD specifier: ^0.5.0-alpha.87 version: 0.5.0-alpha.91(expo@49.0.21)(react-native@0.73.2) @@ -590,6 +596,10 @@ importers: specifier: 0.5.0-alpha.87 version: 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) >>>>>>> 63efb70 (fix: resolved merge issues) +======= + specifier: 0.5.0-alpha.93 + version: 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) +>>>>>>> 7db39fe (feat: added transaction endorsement) '@elastic/ecs-winston-format': specifier: ^1.5.0 version: 1.5.2 @@ -799,6 +809,7 @@ packages: - chokidar dev: true +<<<<<<< HEAD <<<<<<< HEAD /@astronautlabs/jsonpath@1.1.2: resolution: {integrity: sha512-FqL/muoreH7iltYC1EB5Tvox5E8NSOOPGkgns4G+qxRKl6k5dxEVljUjB5NcKESzkqwnUqWjSZkL61XGYOuV+A==} @@ -807,11 +818,15 @@ packages: ======= /@aries-framework/anoncreds-rs@0.5.0-alpha.87(@hyperledger/anoncreds-shared@0.2.0-dev.8)(expo@49.0.21)(react-native@0.73.2): resolution: {integrity: sha512-5SOfD65roN9A9WTJ+93yBdB+OcgUMhaoF9f1EDvMnneB0u80Yy+YLxEDs9QVcDJghh5mu7LlxfjGU8GLaaV7Bw==} +======= + /@aries-framework/anoncreds-rs@0.5.0-alpha.93(@hyperledger/anoncreds-shared@0.2.0-dev.8)(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-jiSIjdT3CsW98/5soWTzgKTZhCHIDzM8lQhFgaads4V+1L6a/3+ZMz0lQK7CZa1Pvd1v6it92Zd2ULMnqnMd+A==} +>>>>>>> 7db39fe (feat: added transaction endorsement) peerDependencies: '@hyperledger/anoncreds-shared': ^0.2.0-dev.5 dependencies: - '@aries-framework/anoncreds': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) - '@aries-framework/core': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/anoncreds': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/core': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@hyperledger/anoncreds-shared': 0.2.0-dev.8 class-transformer: 0.5.1 class-validator: 0.14.0 @@ -825,10 +840,10 @@ packages: - web-streams-polyfill dev: false - /@aries-framework/anoncreds@0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2): - resolution: {integrity: sha512-z1VtGt10INv8hYlraGpIsr8jRQBFMFGAAT107ariBHdAu+jXw8ajD1Z7VbuEHT6mxOJUd3kYxfEUchYTC88mLg==} + /@aries-framework/anoncreds@0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-xoDx9LpvxMD8Jci0AwlzEHJRdAat9XOF2niUOzKSbWy9WBUfgbY836mMEe05hsJXgmjGTXwfL83NCqznOdEOFg==} dependencies: - '@aries-framework/core': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/core': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) bn.js: 5.2.1 class-transformer: 0.5.1 class-validator: 0.14.0 @@ -841,12 +856,12 @@ packages: - web-streams-polyfill dev: false - /@aries-framework/askar@0.5.0-alpha.87(@hyperledger/aries-askar-shared@0.2.0-dev.5)(expo@49.0.21)(react-native@0.73.2): - resolution: {integrity: sha512-KcWhKdekxnKJF/rxDrXcgBsL5UO8cd8dBZwSbtSTYP/VANb8OPakd2fw0MvSf3HF4U8JQtU0fK8taAK4tOy1Gw==} + /@aries-framework/askar@0.5.0-alpha.93(@hyperledger/aries-askar-shared@0.2.0-dev.5)(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-2oSIWQ+pV1zzCwBLhvsXBX1ZuM6TeH74XLbjcZmcuRbSkc1GQwTNAYg+zUS2RyfAXiWKzwHyqXLhVWjhjmUTnw==} peerDependencies: '@hyperledger/aries-askar-shared': ^0.2.0-dev.5 dependencies: - '@aries-framework/core': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/core': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@hyperledger/aries-askar-shared': 0.2.0-dev.5 bn.js: 5.2.1 class-transformer: 0.5.1 @@ -861,8 +876,8 @@ packages: - web-streams-polyfill dev: false - /@aries-framework/core@0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2): - resolution: {integrity: sha512-8V0HsaakhGD9WuCz3WIYpBtD7vCYDhFYCKxXcGXEpJ76Ae3kTUpQSqhbZpFXBvccz8UalzYZtTtsi4YXpyaj3w==} + /@aries-framework/core@0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-mxF45NfUnBDW4/fQY2g5x5UxCk8GTAfuQb9v2zWOUY8y+qVd35QApkDBqJIvAl1D91X5+V6xRgTnW/Cluq32aA==} dependencies: '@digitalcredentials/jsonld': 5.2.2(expo@49.0.21)(react-native@0.73.2) '@digitalcredentials/jsonld-signatures': 9.3.2(expo@49.0.21)(react-native@0.73.2) @@ -902,13 +917,13 @@ packages: - web-streams-polyfill dev: false - /@aries-framework/indy-vdr@0.5.0-alpha.87(@hyperledger/indy-vdr-shared@0.2.0-dev.6)(expo@49.0.21)(react-native@0.73.2): - resolution: {integrity: sha512-rj3hqrq2MggqKp8P06edyTXWINKrtcXpFSFd4jG8Ttr5ObR9vdya0G7EdFT7tKHtGkqD8/qbyDF2D7woZMFEkg==} + /@aries-framework/indy-vdr@0.5.0-alpha.93(@hyperledger/indy-vdr-shared@0.2.0-dev.6)(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-xJMn1snLnA/rWvix837CkGc31ss5rcQw316dK+93YG1jh18KuqsMNBgGRGxrYdT8BeP6CwJisTz15KU7QmJIEA==} peerDependencies: '@hyperledger/indy-vdr-shared': ^0.2.0-dev.6 dependencies: - '@aries-framework/anoncreds': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) - '@aries-framework/core': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/anoncreds': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/core': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@hyperledger/indy-vdr-shared': 0.2.0-dev.6 transitivePeerDependencies: - domexception @@ -918,12 +933,12 @@ packages: - web-streams-polyfill dev: false - /@aries-framework/node@0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2): - resolution: {integrity: sha512-jXNNaGMF/qNCGI5LGyLgZ3cf7MMYNpthh3R+i10jnwFTXH+DjgNy8l+fQLx867T+Hv7+4c+belse6YAtGRZ80Q==} + /@aries-framework/node@0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-Ieorxky6fmayKxAMb7b7JbsCTja9enhMdeLp5UEpuWVWA2I/IQFSyAGFgLs7scTn40dQ4Fe8MvhYYk6OIpDGtw==} dependencies: '@2060.io/ffi-napi': 4.0.8 '@2060.io/ref-napi': 3.0.6 - '@aries-framework/core': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/core': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) '@types/express': 4.17.21 express: 4.18.2 ws: 8.16.0 @@ -938,10 +953,10 @@ packages: - web-streams-polyfill dev: false - /@aries-framework/tenants@0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2): - resolution: {integrity: sha512-txx2hZjQ5lpcS+vbfaw9ZTNF+SA1DfYuLmGwjdVMNUmMxlCr8siks4MV1h194dGecC53w44Ab+H6AozvRDktog==} + /@aries-framework/tenants@0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2): + resolution: {integrity: sha512-xgfFqOhh5EUAtCmS6MKGjfCt02WZgYF4LtE1gRZYD3uq8W5BZHSSF11QcWieO6Wl4Hnnjuz7d+p+f0WRju8BVg==} dependencies: - '@aries-framework/core': 0.5.0-alpha.87(expo@49.0.21)(react-native@0.73.2) + '@aries-framework/core': 0.5.0-alpha.93(expo@49.0.21)(react-native@0.73.2) async-mutex: 0.4.0 transitivePeerDependencies: - domexception @@ -4584,7 +4599,7 @@ packages: dependencies: '@nestjs/axios': 3.0.1(@nestjs/common@10.3.0)(axios@1.6.5)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/common': 10.3.0(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/core': 10.3.0(@nestjs/common@10.3.0)(@nestjs/microservices@10.3.0)(@nestjs/platform-express@10.3.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/core': 10.3.0(@nestjs/common@10.3.0)(@nestjs/microservices@10.3.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/microservices': 10.3.0(@nestjs/common@10.3.0)(@nestjs/core@10.3.0)(nats@2.19.0)(reflect-metadata@0.1.14)(rxjs@7.8.1) boxen: 5.1.2 check-disk-space: 3.4.0 -- GitLab