diff --git a/__tests__/localMemoryStoreAgent.test.ts b/__tests__/localMemoryStoreAgent.test.ts new file mode 100644 index 000000000..a59ae406b --- /dev/null +++ b/__tests__/localMemoryStoreAgent.test.ts @@ -0,0 +1,166 @@ +import { + createAgent, + TAgent, + IDIDManager, + IResolver, + IKeyManager, + IDataStore, + IMessageHandler, + IAgentOptions, +} from '../packages/core/src' +import { MessageHandler } from '../packages/message-handler/src' +import { KeyManager, MemoryKeyStore } from '../packages/key-manager/src' +import { DIDManager, MemoryDIDStore } from '../packages/did-manager/src' +import { createConnection, Connection } from 'typeorm' +import { DIDResolverPlugin } from '../packages/did-resolver/src' +import { JwtMessageHandler } from '../packages/did-jwt/src' +import { CredentialIssuer, ICredentialIssuer, W3cMessageHandler } from '../packages/credential-w3c/src' +import { EthrDIDProvider } from '../packages/did-provider-ethr/src' +import { WebDIDProvider } from '../packages/did-provider-web/src' +import { DIDComm, DIDCommMessageHandler, IDIDComm } from '../packages/did-comm/src' +import { + SelectiveDisclosure, + ISelectiveDisclosure, + SdrMessageHandler, +} from '../packages/selective-disclosure/src' +import { KeyManagementSystem, SecretBox } from '../packages/kms-local/src' +import { + Entities, + IDataStoreORM, + DataStore, + DataStoreORM, +} from '../packages/data-store/src' +import { Resolver } from 'did-resolver' +import { getResolver as ethrDidResolver } from 'ethr-did-resolver' +import { getResolver as webDidResolver } from 'web-did-resolver' +import fs from 'fs' + +jest.setTimeout(30000) + +// Shared tests +import verifiableData from './shared/verifiableData' +import handleSdrMessage from './shared/handleSdrMessage' +import resolveDid from './shared/resolveDid' +import webDidFlow from './shared/webDidFlow' +import saveClaims from './shared/saveClaims' +import documentationExamples from './shared/documentationExamples' +import keyManager from './shared/keyManager' +import didManager from './shared/didManager' +import messageHandler from './shared/messageHandler' + +const databaseFile = 'local-database2.sqlite' +const infuraProjectId = '5ffc47f65c4042ce847ef66a3fa70d4c' +const secretKey = '29739248cad1bd1a0fc4d9b75cd4d2990de535baf5caadfdf8d8f86664aa830c' + +let agent: TAgent< + IDIDManager & + IKeyManager & + IDataStore & + IDataStoreORM & + IResolver & + IMessageHandler & + IDIDComm & + ICredentialIssuer & + ISelectiveDisclosure +> +let dbConnection: Promise + +const setup = async (options?: IAgentOptions): Promise => { + dbConnection = createConnection({ + type: 'sqlite', + database: databaseFile, + synchronize: true, + logging: false, + entities: Entities, + }) + + agent = createAgent< + IDIDManager & + IKeyManager & + IDataStore & + IDataStoreORM & + IResolver & + IMessageHandler & + IDIDComm & + ICredentialIssuer & + ISelectiveDisclosure + >({ + ...options, + context: { + // authenticatedDid: 'did:example:3456' + }, + plugins: [ + new KeyManager({ + store: new MemoryKeyStore(), + kms: { + local: new KeyManagementSystem(), + }, + }), + new DIDManager({ + store: new MemoryDIDStore(), + defaultProvider: 'did:ethr:rinkeby', + providers: { + 'did:ethr': new EthrDIDProvider({ + defaultKms: 'local', + network: 'mainnet', + rpcUrl: 'https://mainnet.infura.io/v3/' + infuraProjectId, + gas: 1000001, + ttl: 60 * 60 * 24 * 30 * 12 + 1, + }), + 'did:ethr:rinkeby': new EthrDIDProvider({ + defaultKms: 'local', + network: 'rinkeby', + rpcUrl: 'https://rinkeby.infura.io/v3/' + infuraProjectId, + gas: 1000001, + ttl: 60 * 60 * 24 * 30 * 12 + 1, + }), + 'did:web': new WebDIDProvider({ + defaultKms: 'local', + }), + }, + }), + new DIDResolverPlugin({ + resolver: new Resolver({ + ...ethrDidResolver({ infuraProjectId }), + ...webDidResolver(), + }), + }), + new DataStore(dbConnection), + new DataStoreORM(dbConnection), + new MessageHandler({ + messageHandlers: [ + new DIDCommMessageHandler(), + new JwtMessageHandler(), + new W3cMessageHandler(), + new SdrMessageHandler(), + ], + }), + new DIDComm(), + new CredentialIssuer(), + new SelectiveDisclosure(), + ], + }) + return true +} + +const tearDown = async (): Promise => { + await (await dbConnection).close() + fs.unlinkSync(databaseFile) + return true +} + +const getAgent = () => agent + +const testContext = { getAgent, setup, tearDown } + +describe('Local in-memory integration tests', () => { + verifiableData(testContext) + handleSdrMessage(testContext) + resolveDid(testContext) + webDidFlow(testContext) + saveClaims(testContext) + documentationExamples(testContext) + keyManager(testContext) + didManager(testContext) + messageHandler(testContext) +}) diff --git a/__tests__/shared/webDidFlow.ts b/__tests__/shared/webDidFlow.ts index 9f433d9a3..6697d71af 100644 --- a/__tests__/shared/webDidFlow.ts +++ b/__tests__/shared/webDidFlow.ts @@ -83,10 +83,8 @@ export default (testContext: { }) it('should query identifiers', async () => { - const identifiers = await agent.dataStoreORMGetIdentifiers() + const identifiers = await agent.didManagerFind() expect(identifiers.length).toEqual(3) - const count = await agent.dataStoreORMGetIdentifiersCount() - expect(count).toEqual(3) }) describe('should create verifiable credential', () => { diff --git a/packages/did-manager/src/index.ts b/packages/did-manager/src/index.ts index 1c99a8fea..a7cf09c22 100644 --- a/packages/did-manager/src/index.ts +++ b/packages/did-manager/src/index.ts @@ -7,3 +7,4 @@ export { DIDManager } from './id-manager' export { AbstractIdentifierProvider } from './abstract-identifier-provider' export { AbstractDIDStore } from './abstract-identifier-store' +export { MemoryDIDStore } from './memory-did-store' diff --git a/packages/did-manager/src/memory-did-store.ts b/packages/did-manager/src/memory-did-store.ts new file mode 100644 index 000000000..5528d2b74 --- /dev/null +++ b/packages/did-manager/src/memory-did-store.ts @@ -0,0 +1,74 @@ +import { IIdentifier } from '@veramo/core' +import { AbstractDIDStore } from './abstract-identifier-store' + +export class MemoryDIDStore extends AbstractDIDStore { + private identifiers: Record = {} + + async get({ + did, + alias, + provider, + }: { + did: string + alias: string + provider: string + }): Promise { + if (did !== undefined && alias === undefined) { + if (!this.identifiers[did]) throw Error('Identifier not found') + return this.identifiers[did] + } else if ( + did === undefined && + alias !== undefined && + provider !== undefined + ) { + for (const key of Object.keys(this.identifiers)) { + if ( + this.identifiers[key].alias === alias && + this.identifiers[key].provider === provider + ) { + return this.identifiers[key] + } + } + } else { + throw Error('Get requires did or (alias and provider)') + } + throw Error('Identifier not found') + } + + async delete({ did }: { did: string }) { + delete this.identifiers[did] + return true + } + + async import(args: IIdentifier) { + const identifier = {...args} + for (const key of identifier.keys) { + if (key.privateKeyHex) { + delete key.privateKeyHex + } + } + this.identifiers[args.did] = identifier + return true + } + + async list(args: { + alias?: string + provider?: string + }): Promise { + let result: IIdentifier[] = [] + + for (const key of Object.keys(this.identifiers)) { + result.push(this.identifiers[key]) + } + + if (args.alias && !args.provider) { + result = result.filter((i) => i.alias === args.alias) + } else if (args.provider && !args.alias) { + result = result.filter((i) => i.provider === args.provider) + } else if (args.provider && args.alias) { + result = result.filter((i) => i.provider === args.provider && i.alias === args.alias) + } + + return result + } +} diff --git a/packages/key-manager/src/index.ts b/packages/key-manager/src/index.ts index 37975ef51..f6f0451d0 100644 --- a/packages/key-manager/src/index.ts +++ b/packages/key-manager/src/index.ts @@ -8,3 +8,4 @@ export { KeyManager } from './key-manager' export { AbstractKeyManagementSystem } from './abstract-key-management-system' export { AbstractKeyStore } from './abstract-key-store' export { AbstractSecretBox } from './abstract-secret-box' +export { MemoryKeyStore } from './memory-key-store' diff --git a/packages/key-manager/src/memory-key-store.ts b/packages/key-manager/src/memory-key-store.ts new file mode 100644 index 000000000..6ce3db338 --- /dev/null +++ b/packages/key-manager/src/memory-key-store.ts @@ -0,0 +1,22 @@ +import { IKey } from '@veramo/core' +import { AbstractKeyStore } from './abstract-key-store' + +export class MemoryKeyStore extends AbstractKeyStore { + private keys: Record = {} + + async get({ kid }: { kid: string }): Promise { + const key = this.keys[kid] + if (!key) throw Error('Key not found') + return key + } + + async delete({ kid }: { kid: string }) { + delete this.keys[kid] + return true + } + + async import(args: IKey) { + this.keys[args.kid] = {...args} + return true + } +}