Skip to content

Commit

Permalink
feat: add generic did resolver (#554)
Browse files Browse the repository at this point in the history
* feat: did:key, did:web, did:sov resolver

Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra authored Jan 5, 2022
1 parent 61695ce commit 8e03f35
Show file tree
Hide file tree
Showing 53 changed files with 2,643 additions and 37 deletions.
10 changes: 7 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
},
"dependencies": {
"@multiformats/base-x": "^4.0.1",
"@types/indy-sdk": "^1.16.6",
"@stablelib/ed25519": "^1.0.2",
"@stablelib/sha256": "^1.0.1",
"@types/indy-sdk": "^1.16.8",
"@types/node-fetch": "^2.5.10",
"@types/ws": "^7.4.4",
"abort-controller": "^3.0.0",
Expand All @@ -33,18 +35,20 @@
"buffer": "^6.0.3",
"class-transformer": "0.5.1",
"class-validator": "0.13.1",
"js-sha256": "^0.9.0",
"did-resolver": "^3.1.3",
"lru_map": "^0.4.1",
"luxon": "^1.27.0",
"make-error": "^1.3.6",
"multibase": "^4.0.4",
"multiformats": "^9.4.14",
"multihashes": "^4.0.2",
"object-inspect": "^1.10.3",
"query-string": "^7.0.1",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.1.0",
"tsyringe": "^4.5.0",
"uuid": "^8.3.2"
"uuid": "^8.3.2",
"web-did-resolver": "^2.0.8"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
Expand Down
19 changes: 11 additions & 8 deletions packages/core/src/agent/Agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { AriesFrameworkError } from '../error'
import { BasicMessagesModule } from '../modules/basic-messages/BasicMessagesModule'
import { ConnectionsModule } from '../modules/connections/ConnectionsModule'
import { CredentialsModule } from '../modules/credentials/CredentialsModule'
import { DidsModule } from '../modules/dids/DidsModule'
import { DiscoverFeaturesModule } from '../modules/discover-features'
import { LedgerModule } from '../modules/ledger/LedgerModule'
import { ProofsModule } from '../modules/proofs/ProofsModule'
Expand Down Expand Up @@ -45,14 +46,15 @@ export class Agent {
private _isInitialized = false
public messageSubscription: Subscription

public readonly connections!: ConnectionsModule
public readonly proofs!: ProofsModule
public readonly basicMessages!: BasicMessagesModule
public readonly ledger!: LedgerModule
public readonly credentials!: CredentialsModule
public readonly mediationRecipient!: RecipientModule
public readonly mediator!: MediatorModule
public readonly discovery!: DiscoverFeaturesModule
public readonly connections: ConnectionsModule
public readonly proofs: ProofsModule
public readonly basicMessages: BasicMessagesModule
public readonly ledger: LedgerModule
public readonly credentials: CredentialsModule
public readonly mediationRecipient: RecipientModule
public readonly mediator: MediatorModule
public readonly discovery: DiscoverFeaturesModule
public readonly dids: DidsModule
public readonly wallet: Wallet

public constructor(initialConfig: InitConfig, dependencies: AgentDependencies) {
Expand Down Expand Up @@ -102,6 +104,7 @@ export class Agent {
this.basicMessages = this.container.resolve(BasicMessagesModule)
this.ledger = this.container.resolve(LedgerModule)
this.discovery = this.container.resolve(DiscoverFeaturesModule)
this.dids = this.container.resolve(DidsModule)

// Listen for new messages (either from transports or somewhere else in the framework / extensions)
this.messageSubscription = this.eventEmitter
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/modules/credentials/CredentialUtils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { LinkedAttachment } from '../../utils/LinkedAttachment'
import type { CredValues } from 'indy-sdk'

import { hash as sha256 } from '@stablelib/sha256'
import BigNumber from 'bn.js'
import { sha256 } from 'js-sha256'

import { AriesFrameworkError } from '../../error/AriesFrameworkError'
import { encodeAttachment } from '../../utils/attachment'
import { Buffer } from '../../utils/buffer'
import { isBoolean, isNumber, isString } from '../../utils/type'

import { CredentialPreview, CredentialPreviewAttribute } from './messages/CredentialPreview'
Expand Down Expand Up @@ -164,7 +165,7 @@ export class CredentialUtils {
value = 'None'
}

return new BigNumber(sha256.array(value as string)).toString()
return new BigNumber(sha256(Buffer.from(value as string))).toString()
}

private static isInt32(number: number) {
Expand Down
18 changes: 18 additions & 0 deletions packages/core/src/modules/dids/DidsModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { DidResolutionOptions } from './types'

import { Lifecycle, scoped } from 'tsyringe'

import { DidResolverService } from './services/DidResolverService'

@scoped(Lifecycle.ContainerScoped)
export class DidsModule {
private resolverService: DidResolverService

public constructor(resolverService: DidResolverService) {
this.resolverService = resolverService
}

public resolve(didUrl: string, options?: DidResolutionOptions) {
return this.resolverService.resolve(didUrl, options)
}
}
63 changes: 63 additions & 0 deletions packages/core/src/modules/dids/__tests__/DidKeyBls12381G1.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { BufferEncoder } from '../../../utils/BufferEncoder'
import { JsonTransformer } from '../../../utils/JsonTransformer'
import { Buffer } from '../../../utils/buffer'
import { DidKey, KeyType } from '../domain/DidKey'

import didKeyBls12381g1Fixture from './__fixtures__/didKeyBls12381g1.json'

const TEST_BLS12381G1_BASE58_KEY = '6FywSzB5BPd7xehCo1G4nYHAoZPMMP3gd4PLnvgA6SsTsogtz8K7RDznqLpFPLZXAE'
const TEST_BLS12381G1_FINGERPRINT = 'z3tEFALUKUzzCAvytMHX8X4SnsNsq6T5tC5Zb18oQEt1FqNcJXqJ3AA9umgzA9yoqPBeWA'
const TEST_BLS12381G1_DID = `did:key:${TEST_BLS12381G1_FINGERPRINT}`
const TEST_BLS12381G1_KEY_ID = `${TEST_BLS12381G1_DID}#${TEST_BLS12381G1_FINGERPRINT}`
const TEST_BLS12381G1_PREFIX_BYTES = Buffer.concat([
new Uint8Array([234, 1]),
BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY),
])

describe('DidKey', () => {
describe('bls12381g1', () => {
it('creates a DidKey instance from public key bytes and bls12381g1 key type', async () => {
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY)

const didKey = DidKey.fromPublicKey(publicKeyBytes, KeyType.BLS12381G1)

expect(didKey.did).toBe(TEST_BLS12381G1_DID)
})

it('creates a DidKey instance from a base58 encoded public key and bls12381g1 key type', async () => {
const didKey = DidKey.fromPublicKeyBase58(TEST_BLS12381G1_BASE58_KEY, KeyType.BLS12381G1)

expect(didKey.did).toBe(TEST_BLS12381G1_DID)
})

it('creates a DidKey instance from a fingerprint', async () => {
const didKey = DidKey.fromFingerprint(TEST_BLS12381G1_FINGERPRINT)

expect(didKey.did).toBe(TEST_BLS12381G1_DID)
})

it('creates a DidKey instance from a did', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G1_DID)

expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1_BASE58_KEY)
})

it('should correctly calculate the getter properties', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G1_DID)

expect(didKey.fingerprint).toBe(TEST_BLS12381G1_FINGERPRINT)
expect(didKey.did).toBe(TEST_BLS12381G1_DID)
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1_BASE58_KEY)
expect(didKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY))
expect(didKey.keyType).toBe(KeyType.BLS12381G1)
expect(didKey.keyId).toBe(TEST_BLS12381G1_KEY_ID)
expect(didKey.prefixedPublicKey.equals(TEST_BLS12381G1_PREFIX_BYTES)).toBe(true)
})

it('should return a valid did:key did document for the did', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G1_DID)

expect(JsonTransformer.toJSON(didKey.didDocument)).toMatchObject(didKeyBls12381g1Fixture)
})
})
})
100 changes: 100 additions & 0 deletions packages/core/src/modules/dids/__tests__/DidKeyBls12381G1G2.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { BufferEncoder } from '../../../utils/BufferEncoder'
import { JsonTransformer } from '../../../utils/JsonTransformer'
import { Buffer } from '../../../utils/buffer'
import { DidKey, KeyType } from '../domain/DidKey'

import didKeyBls12381g1g2Fixture from './__fixtures__/didKeyBls12381g1g2.json'

const TEST_BLS12381G1G2_BASE58_KEY =
'AQ4MiG1JKHmM5N4CgkF9uQ484PHN7gXB3ctF4ayL8hT6FdD6rcfFS3ZnMNntYsyJBckfNPf3HL8VU8jzgyT3qX88Yg3TeF2NkG2aZnJDNnXH1jkJStWMxjLw22LdphqAj1rSorsDhHjE8Rtz61bD6FP9aPokQUDVpZ4zXqsXVcxJ7YEc66TTLTTPwQPS7uNM4u2Fs'
const TEST_BLS12381G1G2_FINGERPRINT =
'z5TcESXuYUE9aZWYwSdrUEGK1HNQFHyTt4aVpaCTVZcDXQmUheFwfNZmRksaAbBneNm5KyE52SdJeRCN1g6PJmF31GsHWwFiqUDujvasK3wTiDr3vvkYwEJHt7H5RGEKYEp1ErtQtcEBgsgY2DA9JZkHj1J9HZ8MRDTguAhoFtR4aTBQhgnkP4SwVbxDYMEZoF2TMYn3s'
const TEST_BLS12381G1G2_DID = `did:key:${TEST_BLS12381G1G2_FINGERPRINT}`

const TEST_BLS12381G1_BASE58_KEY = '7BVES4h78wzabPAfMhchXyH5d8EX78S5TtzePH2YkftWcE6by9yj3NTAv9nsyCeYch'
const TEST_BLS12381G1_FINGERPRINT = 'z3tEG5qmJZX29jJSX5kyhDR5YJNnefJFdwTxRqk6zbEPv4Pf2xF12BpmXv9NExxSRFGfxd'
const TEST_BLS12381G1_DID = `did:key:${TEST_BLS12381G1_FINGERPRINT}`

const TEST_BLS12381G2_BASE58_KEY =
'26d2BdqELsXg7ZHCWKL2D5Y2S7mYrpkdhJemSEEvokd4qy4TULJeeU44hYPGKo4x4DbBp5ARzkv1D6xuB3bmhpdpKAXuXtode67wzh9PCtW8kTqQhH19VSiFZkLNkhe9rtf3'
const TEST_BLS12381G2_FINGERPRINT =
'zUC7LTa4hWtaE9YKyDsMVGiRNqPMN3s4rjBdB3MFi6PcVWReNfR72y3oGW2NhNcaKNVhMobh7aHp8oZB3qdJCs7RebM2xsodrSm8MmePbN25NTGcpjkJMwKbcWfYDX7eHCJjPGM'
const TEST_BLS12381G2_DID = `did:key:${TEST_BLS12381G2_FINGERPRINT}`

const TEST_BLS12381G1G2_PREFIX_BYTES = Buffer.concat([
new Uint8Array([238, 1]),
BufferEncoder.fromBase58(TEST_BLS12381G1G2_BASE58_KEY),
])

describe('DidKey', () => {
describe('bls12381g1g2', () => {
it('creates a DidKey instance from public key bytes and bls12381g1g2 key type', async () => {
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G1G2_BASE58_KEY)

const didKey = DidKey.fromPublicKey(publicKeyBytes, KeyType.BLS12381G1G2)

expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
})

it('creates a DidKey instance from a base58 encoded public key and bls12381g1g2 key type', async () => {
const didKey = DidKey.fromPublicKeyBase58(TEST_BLS12381G1G2_BASE58_KEY, KeyType.BLS12381G1G2)

expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
})

it('creates a DidKey instance from a fingerprint', async () => {
const didKey = DidKey.fromFingerprint(TEST_BLS12381G1G2_FINGERPRINT)

expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
})

it('creates a DidKey instance from a did', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)

expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1G2_BASE58_KEY)
})

it('should correctly calculate the getter properties', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)

expect(didKey.fingerprint).toBe(TEST_BLS12381G1G2_FINGERPRINT)
expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1G2_BASE58_KEY)
expect(didKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G1G2_BASE58_KEY))
expect(didKey.keyType).toBe(KeyType.BLS12381G1G2)
expect(didKey.prefixedPublicKey.equals(TEST_BLS12381G1G2_PREFIX_BYTES)).toBe(true)
})

it('should return a valid did:key did document for the did', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)

expect(JsonTransformer.toJSON(didKey.didDocument)).toMatchObject(didKeyBls12381g1g2Fixture)
})

it('should correctly go from g1g2 to g1', async () => {
const g1g2DidKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)

const g1PublicKey = g1g2DidKey.publicKey.slice(0, 48)
const g1DidKey = DidKey.fromPublicKey(g1PublicKey, KeyType.BLS12381G1)

expect(g1DidKey.fingerprint).toBe(TEST_BLS12381G1_FINGERPRINT)
expect(g1DidKey.did).toBe(TEST_BLS12381G1_DID)
expect(g1DidKey.publicKeyBase58).toBe(TEST_BLS12381G1_BASE58_KEY)
expect(g1DidKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY))
expect(g1DidKey.keyType).toBe(KeyType.BLS12381G1)
})

it('should correctly go from g1g2 to g2', async () => {
const g1g2DidKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)

const g2PublicKey = g1g2DidKey.publicKey.slice(48)
const g2DidKey = DidKey.fromPublicKey(g2PublicKey, KeyType.BLS12381G2)

expect(g2DidKey.fingerprint).toBe(TEST_BLS12381G2_FINGERPRINT)
expect(g2DidKey.did).toBe(TEST_BLS12381G2_DID)
expect(g2DidKey.publicKeyBase58).toBe(TEST_BLS12381G2_BASE58_KEY)
expect(g2DidKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY))
expect(g2DidKey.keyType).toBe(KeyType.BLS12381G2)
})
})
})
65 changes: 65 additions & 0 deletions packages/core/src/modules/dids/__tests__/DidKeyBls12381G2.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { BufferEncoder } from '../../../utils/BufferEncoder'
import { JsonTransformer } from '../../../utils/JsonTransformer'
import { Buffer } from '../../../utils/buffer'
import { DidKey, KeyType } from '../domain/DidKey'

import didKeyBls12381g2Fixture from './__fixtures__/didKeyBls12381g2.json'

const TEST_BLS12381G2_BASE58_KEY =
'mxE4sHTpbPcmxNviRVR9r7D2taXcNyVJmf9TBUFS1gRt3j3Ej9Seo59GQeCzYwbQgDrfWCwEJvmBwjLvheAky5N2NqFVzk4kuq3S8g4Fmekai4P622vHqWjFrsioYYDqhf9'
const TEST_BLS12381G2_FINGERPRINT =
'zUC71nmwvy83x1UzNKbZbS7N9QZx8rqpQx3Ee3jGfKiEkZngTKzsRoqobX6wZdZF5F93pSGYYco3gpK9tc53ruWUo2tkBB9bxPCFBUjq2th8FbtT4xih6y6Q1K9EL4Th86NiCGT'
const TEST_BLS12381G2_DID = `did:key:${TEST_BLS12381G2_FINGERPRINT}`
const TEST_BLS12381G2_KEY_ID = `${TEST_BLS12381G2_DID}#${TEST_BLS12381G2_FINGERPRINT}`
const TEST_BLS12381G2_PREFIX_BYTES = Buffer.concat([
new Uint8Array([235, 1]),
BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY),
])

describe('DidKey', () => {
describe('bls12381g2', () => {
it('creates a DidKey instance from public key bytes and bls12381g2 key type', async () => {
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY)

const didKey = DidKey.fromPublicKey(publicKeyBytes, KeyType.BLS12381G2)

expect(didKey.did).toBe(TEST_BLS12381G2_DID)
})

it('creates a DidKey instance from a base58 encoded public key and bls12381g2 key type', async () => {
const didKey = DidKey.fromPublicKeyBase58(TEST_BLS12381G2_BASE58_KEY, KeyType.BLS12381G2)

expect(didKey.did).toBe(TEST_BLS12381G2_DID)
})

it('creates a DidKey instance from a fingerprint', async () => {
const didKey = DidKey.fromFingerprint(TEST_BLS12381G2_FINGERPRINT)

expect(didKey.did).toBe(TEST_BLS12381G2_DID)
})

it('creates a DidKey instance from a did', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G2_DID)

expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G2_BASE58_KEY)
})

it('should correctly calculate the getter properties', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G2_DID)

expect(didKey.fingerprint).toBe(TEST_BLS12381G2_FINGERPRINT)
expect(didKey.did).toBe(TEST_BLS12381G2_DID)
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G2_BASE58_KEY)
expect(didKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY))
expect(didKey.keyType).toBe(KeyType.BLS12381G2)
expect(didKey.keyId).toBe(TEST_BLS12381G2_KEY_ID)
expect(didKey.prefixedPublicKey.equals(TEST_BLS12381G2_PREFIX_BYTES)).toBe(true)
})

it('should return a valid did:key did document for the did', async () => {
const didKey = DidKey.fromDid(TEST_BLS12381G2_DID)

expect(JsonTransformer.toJSON(didKey.didDocument)).toMatchObject(didKeyBls12381g2Fixture)
})
})
})
Loading

0 comments on commit 8e03f35

Please sign in to comment.