diff --git a/packages/vc-handler-ld-local/agent.yml b/packages/vc-handler-ld-local/agent.yml index e7479e2c4..2debeaf30 100644 --- a/packages/vc-handler-ld-local/agent.yml +++ b/packages/vc-handler-ld-local/agent.yml @@ -1,12 +1,15 @@ version: 3.0 constants: - baseUrl: http://localhost:3337 - port: 3337 + baseUrl: http://localhost:3339 + port: 3339 # please use your own X25519 key, this is only an example secretKey: 29739248cad1bd1a0fc4d9b75cd4d2990de535baf5caadfdf8d8f86664aa830c methods: - - issueCredentialUsingLocalClient + - createVerifiableCredentialLDLocal + createVerifiablePresentationLDLocal + verifyPresentationLDLocal + verifyCredentialLDLocal server: baseUrl: @@ -70,8 +73,14 @@ agent: $args: - schemaValidation: false plugins: - - $require: ./packages/vc-handler-ld-local/dist#VcApiIssuer + - $require: '@veramo/credential-ld/build#VeramoLdSignature' + # + # - $require: '@veramo/credential-ld/build#CredentialIssuerLD' + # $args: + # - contextMaps: [] + # suites: [] + - $require: ./packages/vc-handler-ld-local/dist#CredentialHandlerLDLocal $args: - - issueUrl: 'https://vc-api.sphereon.io/services/issue/credentials' - # please use your own authorization token, this is only an example - authorizationToken: 'ey...' + - contextMaps: [] + suites: [] + bindingOverrides: [] diff --git a/packages/vc-handler-ld-local/src/__tests__/restAgent.test.ts b/packages/vc-handler-ld-local/src/__tests__/restAgent.test.ts index 077055638..009db094a 100644 --- a/packages/vc-handler-ld-local/src/__tests__/restAgent.test.ts +++ b/packages/vc-handler-ld-local/src/__tests__/restAgent.test.ts @@ -1,14 +1,11 @@ import 'cross-fetch/polyfill' -import { IAgent, createAgent, IAgentOptions } from '@veramo/core' -import { AgentRestClient } from '@veramo/remote-client' +import { IAgent } from '@veramo/core' import express from 'express' import { Server } from 'http' import { AgentRouter, RequestWithAgentRouter } from '@veramo/remote-server' import { getConfig } from '@veramo/cli/build/setup' import { createObjects } from '@veramo/cli/build/lib/objectCreator' -import { ICredentialHandlerLDLocal } from '../index' -import vcApiIssuerAgentLogic from './shared/vcApiIssuerAgentLogic' -import { CredentialHandlerLDLocal } from '../index' +import { LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' jest.setTimeout(30000) @@ -41,8 +38,9 @@ const getAgent = (options?: IAgentOptions) => */ const setup = async (): Promise => { - const config = getConfig('packages/vc-api-issuer/agent.yml') - config.agent.$args[0].plugins[0].$args[0].authorizationToken = process.env.VC_HTTP_API_AUTH_TOKEN + const config = getConfig('packages/vc-handler-ld-local/agent.yml'); + (config.agent.$args[0].plugins[0].$args[0].contextMaps = [LdDefaultContexts /*, customContext*/]), + (config.agent.$args[0].plugins[0].$args[0].suites = [new VeramoEd25519Signature2018()]) const { agent } = createObjects(config, { agent: '/agent' }) serverAgent = agent @@ -68,11 +66,10 @@ const tearDown = async (): Promise => { return true } -const testContext = { /*getAgent, */setup, tearDown } +const testContext = { /*getAgent, */ setup, tearDown } describe('REST integration tests', () => { xit('handler', () => { // vcApiIssuerAgentLogic(testContext) }) - }) diff --git a/packages/vc-handler-ld-local/src/__tests__/shared/vcApiIssuerAgentLogic.ts b/packages/vc-handler-ld-local/src/__tests__/shared/vcApiIssuerAgentLogic.ts index 5ea78ac0a..0a1003fcc 100644 --- a/packages/vc-handler-ld-local/src/__tests__/shared/vcApiIssuerAgentLogic.ts +++ b/packages/vc-handler-ld-local/src/__tests__/shared/vcApiIssuerAgentLogic.ts @@ -1,15 +1,62 @@ -import { TAgent } from '@veramo/core' -import { ICredentialHandlerLDLocal } from '../../types/ICredentialHandlerLDLocal' +import { CredentialHandlerLDLocal } from '../../agent/CredentialHandlerLDLocal' +import { Resolver } from 'did-resolver' +import { ContextDoc, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' +import { DIDManager, MemoryDIDStore } from '@veramo/did-manager' +import { createAgent, CredentialPayload, IDIDManager, IIdentifier, IKeyManager, IResolver, PresentationPayload, TAgent } from '@veramo/core' +import { KeyManagementSystem } from '@veramo/kms-local' +import { KeyManager, MemoryKeyStore, MemoryPrivateKeyStore } from '@veramo/key-manager' +import { CredentialIssuer, ICredentialIssuer } from '@veramo/credential-w3c' +import { getDidKeyResolver, KeyDIDProvider } from '@veramo/did-provider-key' +import { DIDResolverPlugin } from '@veramo/did-resolver' +import { getUniResolver } from '@sphereon/did-uni-client' +import { LtoDidProvider } from '../../../../lto-did-provider/src/lto-did-provider' +import { IDidConnectionMode } from '../../../../lto-did-provider/src/types/lto-provider-types' +import { ICredentialHandlerLDLocal, MethodNames } from '../../types/ICredentialHandlerLDLocal' type ConfiguredAgent = TAgent export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Promise; tearDown: () => Promise }) => { describe('Issuer Agent Plugin', () => { - let agent: ConfiguredAgent + + let didKeyIdentifier: IIdentifier + let didLtoIdentifier: IIdentifier + let agent: TAgent beforeAll(async () => { - await testContext.setup() - agent = testContext.getAgent() + agent = createAgent({ + plugins: [ + new KeyManager({ + store: new MemoryKeyStore(), + kms: { + local: new KeyManagementSystem(new MemoryPrivateKeyStore()), + }, + }), + new DIDManager({ + providers: { + 'did:key': new KeyDIDProvider({ defaultKms: 'local' }) + }, + store: new MemoryDIDStore(), + defaultProvider: 'did:key', + }), + new DIDResolverPlugin({ + resolver: new Resolver({ + ...getDidKeyResolver(), + }), + }), + new CredentialIssuer(), + new CredentialHandlerLDLocal({ + contextMaps: [LdDefaultContexts /*, customContext*/], + suites: [new VeramoEd25519Signature2018()], + bindingOverrides: new Map([ + // Bindings to test overrides of credential-ld plugin methods + ['createVerifiableCredentialLD', MethodNames.createVerifiableCredentialLDLocal], + ['createVerifiablePresentationLD', MethodNames.createVerifiablePresentationLDLocal], + // We test the verify methods by using the LDLocal versions directly in the tests + ]), + }), + ], + }) + didKeyIdentifier = await agent.didManagerCreate() }) afterAll(async () => { @@ -18,33 +65,21 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro }) it('should issue', async () => { - const credential = { - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - 'https://www.w3.org/2018/credentials/examples/v1', - 'https://w3id.org/vc-revocation-list-2020/v1', - ], - credentialStatus: { - id: 'http://example.gov/credentials/3732#2', - type: 'RevocationList2020Status', - revocationListIndex: '2', - revocationListCredential: 'https://example.github.io/example-repo/revocation-credential.jsonld', - }, + const credential ={ + issuer: didKeyIdentifier.did, + type: ['VerifiableCredential', 'AlumniCredential'], + '@context': ['https://www.w3.org/2018/credentials/v1', 'https://www.w3.org/2018/credentials/examples/v1'], credentialSubject: { - degree: { - name: 'Bachelor of Science and Arts', - type: 'BachelorDegree', + id: didKeyIdentifier.did, + alumniOf: { + id: 'did:example:c276e12ec21ebfeb1f712ebc6f1', + name: 'Example University', }, - id: 'did:example:123', }, - id: 'http://example.gov/credentials/3732', - issuanceDate: '2020-03-16T22:37:26.544Z', - issuer: 'did:example:123', - type: ['VerifiableCredential', 'UniversityDegreeCredential'], } return await expect( - agent.issueCredentialUsingVcApi({ + agent.createVerifiableCredentialLDLocal({ credential, }) ).resolves.not.toBeNull() diff --git a/packages/vc-handler-ld-local/src/agent/CredentialHandlerLDLocal.ts b/packages/vc-handler-ld-local/src/agent/CredentialHandlerLDLocal.ts index 3fb650e56..94ba14665 100644 --- a/packages/vc-handler-ld-local/src/agent/CredentialHandlerLDLocal.ts +++ b/packages/vc-handler-ld-local/src/agent/CredentialHandlerLDLocal.ts @@ -1,6 +1,6 @@ import { CredentialPayload, IAgentContext, IAgentPlugin, IIdentifier, IKey, IResolver, PresentationPayload } from '@veramo/core' -import { schema } from '../index' +import { IBindingOverrides, schema } from '../index' import { ICredentialHandlerLDLocal, IRequiredContext } from '../types/ICredentialHandlerLDLocal' import { VerifiableCredentialSP, VerifiablePresentationSP } from '@sphereon/ssi-sdk-core' import { @@ -37,23 +37,36 @@ export class CredentialHandlerLDLocal implements IAgentPlugin { private ldCredentialModule: LdCredentialModule readonly schema = schema.IVcLocalIssuerJsonLd readonly methods: ICredentialHandlerLDLocal = { + // test: this.createVerifiableCredentialLDLocal.bind(this), // We bind to existing methods as we can act as a drop in replacement. todo: Add config support for this mode - createVerifiableCredentialLD: this.createVerifiableCredentialLDLocal.bind(this), - createVerifiablePresentationLD: this.createVerifiablePresentationLDLocal.bind(this), + // createVerifiableCredentialLD: this.createVerifiableCredentialLDLocal.bind(this), + // createVerifiablePresentationLD: this.createVerifiablePresentationLDLocal.bind(this), verifyPresentationLD: this.verifyPresentationLDLocal.bind(this), verifyCredentialLD: this.verifyCredentialLDLocal.bind(this), - createVerifiableCredentialLDLocal: this.createVerifiableCredentialLDLocal.bind(this), createVerifiablePresentationLDLocal: this.createVerifiablePresentationLDLocal.bind(this), verifyPresentationLDLocal: this.verifyPresentationLDLocal.bind(this), verifyCredentialLDLocal: this.verifyCredentialLDLocal.bind(this), } - constructor(options: { contextMaps: RecordLike>[]; suites: VeramoLdSignature[] }) { + constructor(options: { contextMaps: RecordLike>[]; suites: VeramoLdSignature[]; bindingOverrides?: IBindingOverrides }) { this.ldCredentialModule = new LdCredentialModule({ ldContextLoader: new LdContextLoader({ contextsPaths: options.contextMaps }), ldSuiteLoader: new LdSuiteLoader({ veramoLdSignatures: options.suites }), }) + + this.overrideBindings(options.bindingOverrides) + } + + private overrideBindings(overrides?: IBindingOverrides) { + overrides?.forEach((methodName, bindingName) => { + if (typeof this[methodName] === 'function') { + this.methods[bindingName] = this[methodName].bind(this) + } else { + throw new Error(`Method ${methodName} supplied as target for ${bindingName} is not a valid method in CredentialHandlerLDLocal`) + } + console.log(`binding: this.${bindingName}() -> CredentialHandlerLDLocal.${methodName}()`) + }) } /** {@inheritDoc ICredentialIssuerLDLocal.createVerifiableCredentialLDLocal} */ @@ -161,13 +174,13 @@ export class CredentialHandlerLDLocal implements IAgentPlugin { /** {@inheritdoc ICredentialHandlerLDLocal.verifyCredentialLDLocal} */ public async verifyCredentialLDLocal(args: IVerifyCredentialLDArgs, context: IRequiredContext): Promise { const credential = args.credential - return this.ldCredentialModule.verifyCredential(credential, context) + return this.ldCredentialModule.verifyCredential(credential, context, args.fetchRemoteContexts) } /** {@inheritdoc ICredentialHandlerLDLocal.verifyPresentationLDLocal} */ public async verifyPresentationLDLocal(args: IVerifyPresentationLDArgs, context: IRequiredContext): Promise { const presentation = args.presentation - return this.ldCredentialModule.verifyPresentation(presentation, args.challenge, args.domain, context) + return this.ldCredentialModule.verifyPresentation(presentation, args.challenge, args.domain, context, args.fetchRemoteContexts) } private async findSigningKeyWithId( @@ -175,7 +188,7 @@ export class CredentialHandlerLDLocal implements IAgentPlugin { identifier: IIdentifier, keyRef?: string ): Promise<{ signingKey: IKey; verificationMethodId: string }> { - const extendedKeys: _ExtendedIKey[] = await mapIdentifierKeysToDoc(identifier, 'assertionMethod', context) + const extendedKeys: _ExtendedIKey[] = await mapIdentifierKeysToDoc(identifier, 'verificationMethod', context) let supportedTypes = this.ldCredentialModule.ldSuiteLoader.getAllSignatureSuiteTypes() let signingKey: _ExtendedIKey | undefined let verificationMethodId: string diff --git a/packages/vc-handler-ld-local/src/types/ICredentialHandlerLDLocal.ts b/packages/vc-handler-ld-local/src/types/ICredentialHandlerLDLocal.ts index d0c9ef5ca..c6cb383a5 100644 --- a/packages/vc-handler-ld-local/src/types/ICredentialHandlerLDLocal.ts +++ b/packages/vc-handler-ld-local/src/types/ICredentialHandlerLDLocal.ts @@ -1,4 +1,4 @@ -import { IAgentContext, IDIDManager, IKeyManager, IPluginMethodMap, IResolver } from '@veramo/core' +import { IAgentContext, IDIDManager, IKeyManager, IPluginMethod, IPluginMethodMap, IResolver } from '@veramo/core' import { VerifiableCredentialSP, VerifiablePresentationSP } from '@sphereon/ssi-sdk-core' import { ICreateVerifiableCredentialLDArgs, @@ -9,11 +9,27 @@ import { export interface ICredentialHandlerLDLocal extends IPluginMethodMap { createVerifiableCredentialLDLocal(args: ICreateVerifiableCredentialLDArgs, context: IRequiredContext): Promise + createVerifiablePresentationLDLocal(args: ICreateVerifiablePresentationLDArgs, context: IRequiredContext): Promise + verifyCredentialLDLocal(args: IVerifyCredentialLDArgs, context: IRequiredContext): Promise + verifyPresentationLDLocal(args: IVerifyPresentationLDArgs, context: IRequiredContext): Promise } +/** + * Plugin method map interface + * @public + */ +export enum MethodNames { + createVerifiableCredentialLDLocal = 'createVerifiableCredentialLDLocal', + createVerifiablePresentationLDLocal = 'createVerifiablePresentationLDLocal', + verifyCredentialLDLocal = 'verifyCredentialLDLocal', + verifyPresentationLDLocal = 'verifyPresentationLDLocal', +} + +export type IBindingOverrides = Map + export enum events { CREDENTIAL_ISSUED = 'credentialIssued', }