Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pnpm test:watch
```

If you are running Visual Studio Code, there are some launch configurations available that can be used as template for
step by step debugging.
step by step debugging.

### Building a plugin

Expand Down
160 changes: 160 additions & 0 deletions __tests__/bbs.agent.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// noinspection ES6PreferShortImport

/**
* This runs a suite of ./shared tests using an agent configured for local operations,
* using a SQLite db for storage of credentials, presentations, messages as well as keys and DIDs.
*
* This suite also runs a ganache local blockchain to run through some examples of DIDComm using did:ethr identifiers.
*/

import { createAgent } from '../packages/core/src/index.js'
import {
IAgentOptions,
ICredentialPlugin,
IDataStore,
IDataStoreORM,
IDIDManager,
IKeyManager,
IResolver,
TAgent,
} from '../packages/core-types/src/index.js'
import { DIDManager } from '../packages/did-manager/src/index.js'
import { DIDResolverPlugin } from '../packages/did-resolver/src/index.js'
import { CredentialPlugin } from '../packages/credential-w3c/src/index.js'
import { Resolver } from 'did-resolver'
import { EthrDIDProvider } from '../packages/did-provider-ethr/src/index.js'
import { KeyManagementSystem, SecretBox } from '../packages/kms-local/src/index.js'
import {
DataStoreORM,
DIDStore,
Entities,
KeyStore,
migrations,
PrivateKeyStore,
} from '../packages/data-store/src/index.js'
import { DataSource } from 'typeorm'
import { getResolver as ethrDidResolver } from 'ethr-did-resolver'
import * as fs from 'fs'
import { jest } from '@jest/globals'
import * as path from 'path';
import {
ContextDoc,
BbsDefaultContexts,
BbsSelectiveDisclosureCredentialPlugin,
CredentialProviderBBS,
CustomKeyManager,
VeramoBbsBlsSignature
} from '../packages/credential-bbs/src/index.js'
import citizenVocab from "../packages/credential-bbs/src/custom_contexts/citizenVocab.json"
// Shared tests
import verifiableDataBBS from './shared/verifiableDataBBS.js'


jest.setTimeout(120000)
// This will be the secret key for the KMS
const KMS_SECRET_KEY = '11b574d316903ced6cc3f4787bbcc3047d9c72d1da4d83e36fe714ef785d10c1'
jest.setTimeout(600000)

const customContext: Record<string, ContextDoc> = {
"https://w3id.org/citizenship/v1": citizenVocab,
}
let bbsContextMaps = [BbsDefaultContexts, customContext]
let bbsSuites = [new VeramoBbsBlsSignature()]
const bbs = new CredentialProviderBBS({
contextMaps: bbsContextMaps,
suites: bbsSuites
})
let dbConnection: any

let agent: TAgent<
IDIDManager &
IKeyManager &
IDataStore &
IDataStoreORM &
IResolver &
ICredentialPlugin
>
let databaseFile: string
const database_test = path.normalize(path.resolve() + '/__tests__/fixtures/bbs_database_test.sqlite.tmp')

const setup = async (options?: IAgentOptions): Promise<boolean> => {
databaseFile = options?.context?.databaseFile || ':memory:'
dbConnection = new DataSource({
type: 'sqlite',
database: database_test,
synchronize: false,
migrations,
migrationsRun: true,
logging: ['error', 'info', 'warn'],
entities: [...Entities]
}).initialize()

agent = createAgent<IDIDManager & IKeyManager & IDataStore & IDataStoreORM & IResolver &
ICredentialPlugin>({
plugins: [
new CustomKeyManager({
store: new KeyStore(dbConnection),
kms: {
local: new KeyManagementSystem(new PrivateKeyStore(dbConnection, new SecretBox(KMS_SECRET_KEY))),
},
}),
new DIDManager({
store: new DIDStore(dbConnection),
defaultProvider: 'did:ethr:sepolia',
providers: {
'did:ethr:sepolia': new EthrDIDProvider({
defaultKms: 'local',
network: 'sepolia',
rpcUrl: 'https://eth-sepolia.g.alchemy.com/v2/fTk2Z4HtEe0uc2Lt73cIww13r4_REbj8',

name: 'sepolia',
registry: '0x03d5003bf0e79c5f5223588f347eba39afbc3818',
gas: 100000,
ttl: 60 * 60 * 24 * 30 * 12 + 1,
})
},
}),
new DIDResolverPlugin({
resolver: new Resolver({
...ethrDidResolver(
{
networks: [
{
name: 'sepolia',
chainId: 11155111,
rpcUrl: 'https://eth-sepolia.g.alchemy.com/v2/fTk2Z4HtEe0uc2Lt73cIww13r4_REbj8',
registry: '0x03d5003bf0e79c5f5223588f347eba39afbc3818'
}
]
})
}),
}),
new CredentialPlugin({ issuers: [bbs] }),
new BbsSelectiveDisclosureCredentialPlugin({ contextMaps: bbsContextMaps, suites: bbsSuites }),
new DataStoreORM(dbConnection),
],
})
return true
}

const tearDown = async (): Promise<boolean> => {
try {
await (await dbConnection).dropDatabase()
await (await dbConnection).close()
} catch (e) {
// nop
}
try {
fs.unlinkSync(databaseFile)
} catch (e) {
// nop
}
return true
}

const getAgent = () => agent
const testContext = { getAgent, setup, tearDown }

describe('BBS Local integration tests', () => {
verifiableDataBBS(testContext)
})
Binary file added __tests__/fixtures/bbs_database_test.sqlite.tmp
Binary file not shown.
6 changes: 3 additions & 3 deletions __tests__/shared/documentationExamples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default (testContext: {
it('core-types-IDIDManager-didManagerCreate example', async () => {
const identifier = await agent.didManagerCreate({
alias: 'charlie',
provider: 'did:ethr:sepolia',
provider: 'did:ethr',
kms: 'local',
})
})
Expand All @@ -88,14 +88,14 @@ export default (testContext: {
})

const sepoliaIdentifiers = await agent.didManagerFind({
provider: 'did:ethr:goerli',
provider: 'did:ethr',
})
})

it('core-types-IDIDManager-didManagerGetByAlias example', async () => {
const identifier = await agent.didManagerGetByAlias({
alias: 'charlie',
provider: 'did:ethr:goerli',
provider: 'did:ethr',
})
})

Expand Down
178 changes: 178 additions & 0 deletions __tests__/shared/verifiableDataBBS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// noinspection ES6PreferShortImport

import {
ICredentialPlugin,
IDataStore,
IDataStoreORM,
IDIDManager,
IIdentifier,
TAgent,
VerifiableCredential,
VerifiablePresentation,
CredentialPayload,
ICredentialIssuer,
IResolver,
IKeyManager
} from '../../packages/core-types/src'

type ConfiguredAgent = TAgent<
IDIDManager &
IKeyManager &
IDataStore &
IDataStoreORM &
IResolver &
ICredentialPlugin
>

async function createCredentialGeneric(issuer: IIdentifier, agent: TAgent<ICredentialIssuer>, proofFormat: any, keyRef?: string): Promise<VerifiableCredential> {
//KeyRef should only be set if the did document has more than one bbs key
const credential: CredentialPayload = {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/citizenship/v1",
"https://w3id.org/security/bbs/v1"
],
"id": "https://issuer.oidp.uscis.gov/credentials/83627465",
"type": ["VerifiableCredential", "PermanentResidentCard"],
"issuer": issuer.did,
"identifier": "83627465",
"name": "Permanent Resident Card",
"description": "Government of Example Permanent Resident Card.",
"issuanceDate": "2019-12-03T12:19:52Z",
"expirationDate": "2029-12-03T12:19:52Z",
"credentialSubject": {
"id": "did:example:b34ca6cd37bbf23",
"type": ["PermanentResident", "Person"],
"givenName": "JOHN",
"familyName": "SMITH",
"gender": "Male",
"image": "data:image/png;base64,iVBORw0KGgokJggg==",
"residentSince": "2015-01-01",
"lprCategory": "C09",
"lprNumber": "999-999-999",
"commuterClassification": "C1",
"birthCountry": "Bahamas",
"birthDate": "1958-07-17"
}
}
const verifiableCredential = await agent.createVerifiableCredential({
credential,
proofFormat: proofFormat,
//keyRef: (proofFormat != 'bbs') ? undefined : 'b84ba7dac90ecdfc18cce60e37fe9f0f74ed9102150005691f285be4e61b40bd56b5d37d213363caba82f9ecdcc432931715cb5ef0914123d1cd6844460638ab25bccaf41cb34b7448926772ed2bbab5517c9119aceaf14404a78cd59451bd7d'
keyRef: keyRef
//The keyRef is set because the did document has more than one bbs key
})
return verifiableCredential
}

async function createPresentationGeneric(holder: IIdentifier, agent: TAgent<ICredentialIssuer>, verifiableCredential: VerifiableCredential, proofFormat: any, challenge: any, domain: any, keyRef?: string):
Promise<VerifiablePresentation> {
//KeyRef should only be set if the did document has more than one bbs key

return await agent.createVerifiablePresentation({
presentation: {
holder: holder.did,
type: ['Example'],
verifier: [],
verifiableCredential: [verifiableCredential],
},
proofFormat: proofFormat,
//keyRef: (proofFormat != 'bbs') ? undefined : 'b84ba7dac90ecdfc18cce60e37fe9f0f74ed9102150005691f285be4e61b40bd56b5d37d213363caba82f9ecdcc432931715cb5ef0914123d1cd6844460638ab25bccaf41cb34b7448926772ed2bbab5517c9119aceaf14404a78cd59451bd7d',
keyRef: keyRef,
challenge: challenge,
domain: domain
})
}

async function createSelectiveDisclosureCredential(verifiableCredential: VerifiableCredential, agent: TAgent<ICredentialIssuer>): Promise<VerifiableCredential> {

let revealDocument = {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/citizenship/v1",
"https://w3id.org/security/bbs/v1"
],
"type": ["VerifiableCredential", "PermanentResidentCard"],
"credentialSubject": {
"@explicit": true,
"type": ["PermanentResident", "Person"],
"givenName": {},
"familyName": {},
"gender": {}
}
}

let selectiveDisclosureCredential = await agent.createSelectiveDisclosureCredentialBbs({ proofDocument: verifiableCredential, revealDocument })
return selectiveDisclosureCredential;
}

export default (testContext: {
getAgent: () => ConfiguredAgent
setup: () => Promise<boolean>
tearDown: () => Promise<boolean>
}) => {
describe('creating Verifiable Credentials in BBS', () => {
let agent: ConfiguredAgent
let issuer: any
let holder: any
const challenge = 'test_challenge'
const domain = 'test_domain'

beforeAll(async () => {
await testContext.setup()
agent = testContext.getAgent()
issuer = await agent.didManagerGetByAlias({ alias: 'sepolia_1' })
holder = await agent.didManagerGetByAlias({ alias: 'sepolia_3' })
})
//afterAll(testContext.tearDown)

it('credencial bbs', async () => {
let proofFormatVC = 'bbs';
const verifiableCredential = await createCredentialGeneric(issuer, agent, proofFormatVC)
const vcVerified = await agent.verifyCredential({ credential: verifiableCredential })
expect(vcVerified.verified).toEqual(true)
})

it('credencial bbs - presentacion bbs', async () => {
let proofFormatVC = 'bbs';
let proofFormatVP = 'bbs';
//The keyRef is set because the did document has more than one bbs key
const verifiableCredential = await createCredentialGeneric(issuer, agent, proofFormatVC, 'b84ba7dac90ecdfc18cce60e37fe9f0f74ed9102150005691f285be4e61b40bd56b5d37d213363caba82f9ecdcc432931715cb5ef0914123d1cd6844460638ab25bccaf41cb34b7448926772ed2bbab5517c9119aceaf14404a78cd59451bd7d')
const vcVerified = await agent.verifyCredential({ credential: verifiableCredential })
expect(vcVerified.verified).toEqual(true)

const verifiablePresentation = await createPresentationGeneric(holder, agent, verifiableCredential, proofFormatVP, challenge, domain)
//const verifiablePresentation = await createPresentationGeneric(holder, agent, verifiableCredential, proofFormatVP, challenge, domain, 'b84ba7dac90ecdfc18cce60e37fe9f0f74ed9102150005691f285be4e61b40bd56b5d37d213363caba82f9ecdcc432931715cb5ef0914123d1cd6844460638ab25bccaf41cb34b7448926772ed2bbab5517c9119aceaf14404a78cd59451bd7d')
const vpVerified = await agent.verifyPresentation({
presentation: verifiablePresentation,
challenge,
domain,
})
expect(vpVerified.verified).toEqual(true)
})

it('create selective disclosure credential bbs', async () => {
let proofFormatVC = 'bbs';
let proofFormatVP = 'bbs';
const verifiableCredential = await createCredentialGeneric(issuer, agent, proofFormatVC)
const vcVerified = await agent.verifyCredential({ credential: verifiableCredential })
expect(vcVerified.verified).toEqual(true)

const verifiablePresentation = await createPresentationGeneric(holder, agent, verifiableCredential, proofFormatVP, challenge, domain)
const vpVerified = await agent.verifyPresentation({
presentation: verifiablePresentation,
challenge,
domain,
})
expect(vpVerified.verified).toEqual(true)

let selectiveDisclosureCredential = await createSelectiveDisclosureCredential(verifiableCredential, agent)
const selectiveDisclosureCredentialVerified = await agent.verifyDerivedProofBbs({ credential: selectiveDisclosureCredential })
expect(selectiveDisclosureCredentialVerified.verified).toEqual(true)
})


})


}
Loading