Skip to content

Commit 8e03f35

Browse files
authored
feat: add generic did resolver (openwallet-foundation#554)
* feat: did:key, did:web, did:sov resolver Signed-off-by: Timo Glastra <[email protected]>
1 parent 61695ce commit 8e03f35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2643
-37
lines changed

packages/core/package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
},
2525
"dependencies": {
2626
"@multiformats/base-x": "^4.0.1",
27-
"@types/indy-sdk": "^1.16.6",
27+
"@stablelib/ed25519": "^1.0.2",
28+
"@stablelib/sha256": "^1.0.1",
29+
"@types/indy-sdk": "^1.16.8",
2830
"@types/node-fetch": "^2.5.10",
2931
"@types/ws": "^7.4.4",
3032
"abort-controller": "^3.0.0",
@@ -33,18 +35,20 @@
3335
"buffer": "^6.0.3",
3436
"class-transformer": "0.5.1",
3537
"class-validator": "0.13.1",
36-
"js-sha256": "^0.9.0",
38+
"did-resolver": "^3.1.3",
3739
"lru_map": "^0.4.1",
3840
"luxon": "^1.27.0",
3941
"make-error": "^1.3.6",
4042
"multibase": "^4.0.4",
43+
"multiformats": "^9.4.14",
4144
"multihashes": "^4.0.2",
4245
"object-inspect": "^1.10.3",
4346
"query-string": "^7.0.1",
4447
"reflect-metadata": "^0.1.13",
4548
"rxjs": "^7.1.0",
4649
"tsyringe": "^4.5.0",
47-
"uuid": "^8.3.2"
50+
"uuid": "^8.3.2",
51+
"web-did-resolver": "^2.0.8"
4852
},
4953
"devDependencies": {
5054
"@types/bn.js": "^5.1.0",

packages/core/src/agent/Agent.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { AriesFrameworkError } from '../error'
1717
import { BasicMessagesModule } from '../modules/basic-messages/BasicMessagesModule'
1818
import { ConnectionsModule } from '../modules/connections/ConnectionsModule'
1919
import { CredentialsModule } from '../modules/credentials/CredentialsModule'
20+
import { DidsModule } from '../modules/dids/DidsModule'
2021
import { DiscoverFeaturesModule } from '../modules/discover-features'
2122
import { LedgerModule } from '../modules/ledger/LedgerModule'
2223
import { ProofsModule } from '../modules/proofs/ProofsModule'
@@ -45,14 +46,15 @@ export class Agent {
4546
private _isInitialized = false
4647
public messageSubscription: Subscription
4748

48-
public readonly connections!: ConnectionsModule
49-
public readonly proofs!: ProofsModule
50-
public readonly basicMessages!: BasicMessagesModule
51-
public readonly ledger!: LedgerModule
52-
public readonly credentials!: CredentialsModule
53-
public readonly mediationRecipient!: RecipientModule
54-
public readonly mediator!: MediatorModule
55-
public readonly discovery!: DiscoverFeaturesModule
49+
public readonly connections: ConnectionsModule
50+
public readonly proofs: ProofsModule
51+
public readonly basicMessages: BasicMessagesModule
52+
public readonly ledger: LedgerModule
53+
public readonly credentials: CredentialsModule
54+
public readonly mediationRecipient: RecipientModule
55+
public readonly mediator: MediatorModule
56+
public readonly discovery: DiscoverFeaturesModule
57+
public readonly dids: DidsModule
5658
public readonly wallet: Wallet
5759

5860
public constructor(initialConfig: InitConfig, dependencies: AgentDependencies) {
@@ -102,6 +104,7 @@ export class Agent {
102104
this.basicMessages = this.container.resolve(BasicMessagesModule)
103105
this.ledger = this.container.resolve(LedgerModule)
104106
this.discovery = this.container.resolve(DiscoverFeaturesModule)
107+
this.dids = this.container.resolve(DidsModule)
105108

106109
// Listen for new messages (either from transports or somewhere else in the framework / extensions)
107110
this.messageSubscription = this.eventEmitter

packages/core/src/modules/credentials/CredentialUtils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import type { LinkedAttachment } from '../../utils/LinkedAttachment'
22
import type { CredValues } from 'indy-sdk'
33

4+
import { hash as sha256 } from '@stablelib/sha256'
45
import BigNumber from 'bn.js'
5-
import { sha256 } from 'js-sha256'
66

77
import { AriesFrameworkError } from '../../error/AriesFrameworkError'
88
import { encodeAttachment } from '../../utils/attachment'
9+
import { Buffer } from '../../utils/buffer'
910
import { isBoolean, isNumber, isString } from '../../utils/type'
1011

1112
import { CredentialPreview, CredentialPreviewAttribute } from './messages/CredentialPreview'
@@ -164,7 +165,7 @@ export class CredentialUtils {
164165
value = 'None'
165166
}
166167

167-
return new BigNumber(sha256.array(value as string)).toString()
168+
return new BigNumber(sha256(Buffer.from(value as string))).toString()
168169
}
169170

170171
private static isInt32(number: number) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { DidResolutionOptions } from './types'
2+
3+
import { Lifecycle, scoped } from 'tsyringe'
4+
5+
import { DidResolverService } from './services/DidResolverService'
6+
7+
@scoped(Lifecycle.ContainerScoped)
8+
export class DidsModule {
9+
private resolverService: DidResolverService
10+
11+
public constructor(resolverService: DidResolverService) {
12+
this.resolverService = resolverService
13+
}
14+
15+
public resolve(didUrl: string, options?: DidResolutionOptions) {
16+
return this.resolverService.resolve(didUrl, options)
17+
}
18+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { BufferEncoder } from '../../../utils/BufferEncoder'
2+
import { JsonTransformer } from '../../../utils/JsonTransformer'
3+
import { Buffer } from '../../../utils/buffer'
4+
import { DidKey, KeyType } from '../domain/DidKey'
5+
6+
import didKeyBls12381g1Fixture from './__fixtures__/didKeyBls12381g1.json'
7+
8+
const TEST_BLS12381G1_BASE58_KEY = '6FywSzB5BPd7xehCo1G4nYHAoZPMMP3gd4PLnvgA6SsTsogtz8K7RDznqLpFPLZXAE'
9+
const TEST_BLS12381G1_FINGERPRINT = 'z3tEFALUKUzzCAvytMHX8X4SnsNsq6T5tC5Zb18oQEt1FqNcJXqJ3AA9umgzA9yoqPBeWA'
10+
const TEST_BLS12381G1_DID = `did:key:${TEST_BLS12381G1_FINGERPRINT}`
11+
const TEST_BLS12381G1_KEY_ID = `${TEST_BLS12381G1_DID}#${TEST_BLS12381G1_FINGERPRINT}`
12+
const TEST_BLS12381G1_PREFIX_BYTES = Buffer.concat([
13+
new Uint8Array([234, 1]),
14+
BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY),
15+
])
16+
17+
describe('DidKey', () => {
18+
describe('bls12381g1', () => {
19+
it('creates a DidKey instance from public key bytes and bls12381g1 key type', async () => {
20+
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY)
21+
22+
const didKey = DidKey.fromPublicKey(publicKeyBytes, KeyType.BLS12381G1)
23+
24+
expect(didKey.did).toBe(TEST_BLS12381G1_DID)
25+
})
26+
27+
it('creates a DidKey instance from a base58 encoded public key and bls12381g1 key type', async () => {
28+
const didKey = DidKey.fromPublicKeyBase58(TEST_BLS12381G1_BASE58_KEY, KeyType.BLS12381G1)
29+
30+
expect(didKey.did).toBe(TEST_BLS12381G1_DID)
31+
})
32+
33+
it('creates a DidKey instance from a fingerprint', async () => {
34+
const didKey = DidKey.fromFingerprint(TEST_BLS12381G1_FINGERPRINT)
35+
36+
expect(didKey.did).toBe(TEST_BLS12381G1_DID)
37+
})
38+
39+
it('creates a DidKey instance from a did', async () => {
40+
const didKey = DidKey.fromDid(TEST_BLS12381G1_DID)
41+
42+
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1_BASE58_KEY)
43+
})
44+
45+
it('should correctly calculate the getter properties', async () => {
46+
const didKey = DidKey.fromDid(TEST_BLS12381G1_DID)
47+
48+
expect(didKey.fingerprint).toBe(TEST_BLS12381G1_FINGERPRINT)
49+
expect(didKey.did).toBe(TEST_BLS12381G1_DID)
50+
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1_BASE58_KEY)
51+
expect(didKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY))
52+
expect(didKey.keyType).toBe(KeyType.BLS12381G1)
53+
expect(didKey.keyId).toBe(TEST_BLS12381G1_KEY_ID)
54+
expect(didKey.prefixedPublicKey.equals(TEST_BLS12381G1_PREFIX_BYTES)).toBe(true)
55+
})
56+
57+
it('should return a valid did:key did document for the did', async () => {
58+
const didKey = DidKey.fromDid(TEST_BLS12381G1_DID)
59+
60+
expect(JsonTransformer.toJSON(didKey.didDocument)).toMatchObject(didKeyBls12381g1Fixture)
61+
})
62+
})
63+
})
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { BufferEncoder } from '../../../utils/BufferEncoder'
2+
import { JsonTransformer } from '../../../utils/JsonTransformer'
3+
import { Buffer } from '../../../utils/buffer'
4+
import { DidKey, KeyType } from '../domain/DidKey'
5+
6+
import didKeyBls12381g1g2Fixture from './__fixtures__/didKeyBls12381g1g2.json'
7+
8+
const TEST_BLS12381G1G2_BASE58_KEY =
9+
'AQ4MiG1JKHmM5N4CgkF9uQ484PHN7gXB3ctF4ayL8hT6FdD6rcfFS3ZnMNntYsyJBckfNPf3HL8VU8jzgyT3qX88Yg3TeF2NkG2aZnJDNnXH1jkJStWMxjLw22LdphqAj1rSorsDhHjE8Rtz61bD6FP9aPokQUDVpZ4zXqsXVcxJ7YEc66TTLTTPwQPS7uNM4u2Fs'
10+
const TEST_BLS12381G1G2_FINGERPRINT =
11+
'z5TcESXuYUE9aZWYwSdrUEGK1HNQFHyTt4aVpaCTVZcDXQmUheFwfNZmRksaAbBneNm5KyE52SdJeRCN1g6PJmF31GsHWwFiqUDujvasK3wTiDr3vvkYwEJHt7H5RGEKYEp1ErtQtcEBgsgY2DA9JZkHj1J9HZ8MRDTguAhoFtR4aTBQhgnkP4SwVbxDYMEZoF2TMYn3s'
12+
const TEST_BLS12381G1G2_DID = `did:key:${TEST_BLS12381G1G2_FINGERPRINT}`
13+
14+
const TEST_BLS12381G1_BASE58_KEY = '7BVES4h78wzabPAfMhchXyH5d8EX78S5TtzePH2YkftWcE6by9yj3NTAv9nsyCeYch'
15+
const TEST_BLS12381G1_FINGERPRINT = 'z3tEG5qmJZX29jJSX5kyhDR5YJNnefJFdwTxRqk6zbEPv4Pf2xF12BpmXv9NExxSRFGfxd'
16+
const TEST_BLS12381G1_DID = `did:key:${TEST_BLS12381G1_FINGERPRINT}`
17+
18+
const TEST_BLS12381G2_BASE58_KEY =
19+
'26d2BdqELsXg7ZHCWKL2D5Y2S7mYrpkdhJemSEEvokd4qy4TULJeeU44hYPGKo4x4DbBp5ARzkv1D6xuB3bmhpdpKAXuXtode67wzh9PCtW8kTqQhH19VSiFZkLNkhe9rtf3'
20+
const TEST_BLS12381G2_FINGERPRINT =
21+
'zUC7LTa4hWtaE9YKyDsMVGiRNqPMN3s4rjBdB3MFi6PcVWReNfR72y3oGW2NhNcaKNVhMobh7aHp8oZB3qdJCs7RebM2xsodrSm8MmePbN25NTGcpjkJMwKbcWfYDX7eHCJjPGM'
22+
const TEST_BLS12381G2_DID = `did:key:${TEST_BLS12381G2_FINGERPRINT}`
23+
24+
const TEST_BLS12381G1G2_PREFIX_BYTES = Buffer.concat([
25+
new Uint8Array([238, 1]),
26+
BufferEncoder.fromBase58(TEST_BLS12381G1G2_BASE58_KEY),
27+
])
28+
29+
describe('DidKey', () => {
30+
describe('bls12381g1g2', () => {
31+
it('creates a DidKey instance from public key bytes and bls12381g1g2 key type', async () => {
32+
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G1G2_BASE58_KEY)
33+
34+
const didKey = DidKey.fromPublicKey(publicKeyBytes, KeyType.BLS12381G1G2)
35+
36+
expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
37+
})
38+
39+
it('creates a DidKey instance from a base58 encoded public key and bls12381g1g2 key type', async () => {
40+
const didKey = DidKey.fromPublicKeyBase58(TEST_BLS12381G1G2_BASE58_KEY, KeyType.BLS12381G1G2)
41+
42+
expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
43+
})
44+
45+
it('creates a DidKey instance from a fingerprint', async () => {
46+
const didKey = DidKey.fromFingerprint(TEST_BLS12381G1G2_FINGERPRINT)
47+
48+
expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
49+
})
50+
51+
it('creates a DidKey instance from a did', async () => {
52+
const didKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)
53+
54+
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1G2_BASE58_KEY)
55+
})
56+
57+
it('should correctly calculate the getter properties', async () => {
58+
const didKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)
59+
60+
expect(didKey.fingerprint).toBe(TEST_BLS12381G1G2_FINGERPRINT)
61+
expect(didKey.did).toBe(TEST_BLS12381G1G2_DID)
62+
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G1G2_BASE58_KEY)
63+
expect(didKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G1G2_BASE58_KEY))
64+
expect(didKey.keyType).toBe(KeyType.BLS12381G1G2)
65+
expect(didKey.prefixedPublicKey.equals(TEST_BLS12381G1G2_PREFIX_BYTES)).toBe(true)
66+
})
67+
68+
it('should return a valid did:key did document for the did', async () => {
69+
const didKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)
70+
71+
expect(JsonTransformer.toJSON(didKey.didDocument)).toMatchObject(didKeyBls12381g1g2Fixture)
72+
})
73+
74+
it('should correctly go from g1g2 to g1', async () => {
75+
const g1g2DidKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)
76+
77+
const g1PublicKey = g1g2DidKey.publicKey.slice(0, 48)
78+
const g1DidKey = DidKey.fromPublicKey(g1PublicKey, KeyType.BLS12381G1)
79+
80+
expect(g1DidKey.fingerprint).toBe(TEST_BLS12381G1_FINGERPRINT)
81+
expect(g1DidKey.did).toBe(TEST_BLS12381G1_DID)
82+
expect(g1DidKey.publicKeyBase58).toBe(TEST_BLS12381G1_BASE58_KEY)
83+
expect(g1DidKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G1_BASE58_KEY))
84+
expect(g1DidKey.keyType).toBe(KeyType.BLS12381G1)
85+
})
86+
87+
it('should correctly go from g1g2 to g2', async () => {
88+
const g1g2DidKey = DidKey.fromDid(TEST_BLS12381G1G2_DID)
89+
90+
const g2PublicKey = g1g2DidKey.publicKey.slice(48)
91+
const g2DidKey = DidKey.fromPublicKey(g2PublicKey, KeyType.BLS12381G2)
92+
93+
expect(g2DidKey.fingerprint).toBe(TEST_BLS12381G2_FINGERPRINT)
94+
expect(g2DidKey.did).toBe(TEST_BLS12381G2_DID)
95+
expect(g2DidKey.publicKeyBase58).toBe(TEST_BLS12381G2_BASE58_KEY)
96+
expect(g2DidKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY))
97+
expect(g2DidKey.keyType).toBe(KeyType.BLS12381G2)
98+
})
99+
})
100+
})
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { BufferEncoder } from '../../../utils/BufferEncoder'
2+
import { JsonTransformer } from '../../../utils/JsonTransformer'
3+
import { Buffer } from '../../../utils/buffer'
4+
import { DidKey, KeyType } from '../domain/DidKey'
5+
6+
import didKeyBls12381g2Fixture from './__fixtures__/didKeyBls12381g2.json'
7+
8+
const TEST_BLS12381G2_BASE58_KEY =
9+
'mxE4sHTpbPcmxNviRVR9r7D2taXcNyVJmf9TBUFS1gRt3j3Ej9Seo59GQeCzYwbQgDrfWCwEJvmBwjLvheAky5N2NqFVzk4kuq3S8g4Fmekai4P622vHqWjFrsioYYDqhf9'
10+
const TEST_BLS12381G2_FINGERPRINT =
11+
'zUC71nmwvy83x1UzNKbZbS7N9QZx8rqpQx3Ee3jGfKiEkZngTKzsRoqobX6wZdZF5F93pSGYYco3gpK9tc53ruWUo2tkBB9bxPCFBUjq2th8FbtT4xih6y6Q1K9EL4Th86NiCGT'
12+
const TEST_BLS12381G2_DID = `did:key:${TEST_BLS12381G2_FINGERPRINT}`
13+
const TEST_BLS12381G2_KEY_ID = `${TEST_BLS12381G2_DID}#${TEST_BLS12381G2_FINGERPRINT}`
14+
const TEST_BLS12381G2_PREFIX_BYTES = Buffer.concat([
15+
new Uint8Array([235, 1]),
16+
BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY),
17+
])
18+
19+
describe('DidKey', () => {
20+
describe('bls12381g2', () => {
21+
it('creates a DidKey instance from public key bytes and bls12381g2 key type', async () => {
22+
const publicKeyBytes = BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY)
23+
24+
const didKey = DidKey.fromPublicKey(publicKeyBytes, KeyType.BLS12381G2)
25+
26+
expect(didKey.did).toBe(TEST_BLS12381G2_DID)
27+
})
28+
29+
it('creates a DidKey instance from a base58 encoded public key and bls12381g2 key type', async () => {
30+
const didKey = DidKey.fromPublicKeyBase58(TEST_BLS12381G2_BASE58_KEY, KeyType.BLS12381G2)
31+
32+
expect(didKey.did).toBe(TEST_BLS12381G2_DID)
33+
})
34+
35+
it('creates a DidKey instance from a fingerprint', async () => {
36+
const didKey = DidKey.fromFingerprint(TEST_BLS12381G2_FINGERPRINT)
37+
38+
expect(didKey.did).toBe(TEST_BLS12381G2_DID)
39+
})
40+
41+
it('creates a DidKey instance from a did', async () => {
42+
const didKey = DidKey.fromDid(TEST_BLS12381G2_DID)
43+
44+
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G2_BASE58_KEY)
45+
})
46+
47+
it('should correctly calculate the getter properties', async () => {
48+
const didKey = DidKey.fromDid(TEST_BLS12381G2_DID)
49+
50+
expect(didKey.fingerprint).toBe(TEST_BLS12381G2_FINGERPRINT)
51+
expect(didKey.did).toBe(TEST_BLS12381G2_DID)
52+
expect(didKey.publicKeyBase58).toBe(TEST_BLS12381G2_BASE58_KEY)
53+
expect(didKey.publicKey).toEqual(BufferEncoder.fromBase58(TEST_BLS12381G2_BASE58_KEY))
54+
expect(didKey.keyType).toBe(KeyType.BLS12381G2)
55+
expect(didKey.keyId).toBe(TEST_BLS12381G2_KEY_ID)
56+
expect(didKey.prefixedPublicKey.equals(TEST_BLS12381G2_PREFIX_BYTES)).toBe(true)
57+
})
58+
59+
it('should return a valid did:key did document for the did', async () => {
60+
const didKey = DidKey.fromDid(TEST_BLS12381G2_DID)
61+
62+
expect(JsonTransformer.toJSON(didKey.didDocument)).toMatchObject(didKeyBls12381g2Fixture)
63+
})
64+
})
65+
})

0 commit comments

Comments
 (0)