Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add generic did resolver #554

Merged
merged 20 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that those deps will work with React Native?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know of other react native wallets using the did-resolver library, so pretty sure this will work!

I'll make sure to do a test run to be sure!

},
"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
4 changes: 2 additions & 2 deletions packages/core/src/modules/credentials/CredentialUtils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
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'
Expand Down Expand Up @@ -164,7 +164,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()
TimoGlastra marked this conversation as resolved.
Show resolved Hide resolved
}

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('should correctly create a DidKey instance from public key bytes and bls12381g1 key type', async () => {
TimoGlastra marked this conversation as resolved.
Show resolved Hide resolved
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY)

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

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

it('should correctly create 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('should correctly create a DidKey instance from a fingerprint', async () => {
const didKey = DidKey.fromFingerprint(TEST_BLS12381G1_FINGERPRINT)

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

it('should correctly create 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('should correctly create 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('should correctly create 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('should correctly create a DidKey instance from a fingerprint', async () => {
const didKey = DidKey.fromFingerprint(TEST_BLS12381G1G2_FINGERPRINT)

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

it('should correctly create 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('should correctly create 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('should correctly create 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('should correctly create a DidKey instance from a fingerprint', async () => {
const didKey = DidKey.fromFingerprint(TEST_BLS12381G2_FINGERPRINT)

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

it('should correctly create 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)
})
})
})