Skip to content

Commit

Permalink
feat: add MemoryDIDStore and MemoryKeyStore (#447)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonas-notcat authored Apr 8, 2021
1 parent 6888e3c commit 5ab1792
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 3 deletions.
166 changes: 166 additions & 0 deletions __tests__/localMemoryStoreAgent.test.ts
Original file line number Diff line number Diff line change
@@ -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<Connection>

const setup = async (options?: IAgentOptions): Promise<boolean> => {
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<boolean> => {
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)
})
4 changes: 1 addition & 3 deletions __tests__/shared/webDidFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/did-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
74 changes: 74 additions & 0 deletions packages/did-manager/src/memory-did-store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { IIdentifier } from '@veramo/core'
import { AbstractDIDStore } from './abstract-identifier-store'

export class MemoryDIDStore extends AbstractDIDStore {
private identifiers: Record<string, IIdentifier> = {}

async get({
did,
alias,
provider,
}: {
did: string
alias: string
provider: string
}): Promise<IIdentifier> {
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<IIdentifier[]> {
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
}
}
1 change: 1 addition & 0 deletions packages/key-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
22 changes: 22 additions & 0 deletions packages/key-manager/src/memory-key-store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { IKey } from '@veramo/core'
import { AbstractKeyStore } from './abstract-key-store'

export class MemoryKeyStore extends AbstractKeyStore {
private keys: Record<string, IKey> = {}

async get({ kid }: { kid: string }): Promise<IKey> {
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
}
}

0 comments on commit 5ab1792

Please sign in to comment.