@interop/did-web-resolver 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/DidWebResolver.d.ts +147 -0
- package/dist/esm/DidWebResolver.d.ts.map +1 -0
- package/dist/esm/DidWebResolver.js +322 -0
- package/dist/esm/DidWebResolver.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +6 -5
- package/dist/esm/index.js.map +1 -0
- package/dist/src/DidWebResolver.d.ts +146 -0
- package/dist/src/DidWebResolver.js +329 -0
- package/dist/src/DidWebResolver.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.js +12 -0
- package/dist/src/index.js.map +1 -0
- package/dist/test/DidWebResolver.spec.d.ts +1 -0
- package/dist/test/DidWebResolver.spec.js +183 -0
- package/dist/test/DidWebResolver.spec.js.map +1 -0
- package/package.json +47 -59
- package/src/{DidWebResolver.js → DidWebResolver.ts} +53 -36
- package/src/declarations.d.ts +11 -0
- package/src/{index.js → index.ts} +2 -2
- package/build-dist.sh +0 -14
- package/dist/DidWebResolver.js +0 -383
- package/dist/esm/package.json +0 -3
- package/dist/index.js +0 -14
- package/rollup.config.js +0 -15
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/did-web-resolver",
|
|
3
3
|
"description": "A did:web method Decentralized Identifier (DID) resolver for the did-io library.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dmitri Zagidulin",
|
|
7
7
|
"url": "https://github.com/dmitrizagidulin/"
|
|
@@ -14,92 +14,80 @@
|
|
|
14
14
|
"homepage": "https://github.com/interop-alliance/did-web-driver",
|
|
15
15
|
"bugs": "https://github.com/interop-alliance/did-web-driver/issues",
|
|
16
16
|
"scripts": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
17
|
+
"build": "npm run clear && tsc -d && tsc -p tsconfig.esm.json",
|
|
18
|
+
"clear": "rimraf dist/*",
|
|
19
|
+
"lint": "ts-standard --fix --project tsconfig.spec.json",
|
|
20
20
|
"prepare": "npm run build",
|
|
21
21
|
"rebuild": "npm run clear && npm run build",
|
|
22
|
-
"test": "npm run
|
|
23
|
-
"test-node": "cross-env NODE_ENV=test mocha -r
|
|
24
|
-
"test-karma": "karma start test/karma.conf.js",
|
|
25
|
-
"nyc": "cross-env NODE_ENV=test nyc npm run test-node",
|
|
26
|
-
"standard": "standard --fix"
|
|
22
|
+
"test": "npm run lint && npm run test-node",
|
|
23
|
+
"test-node": "cross-env NODE_ENV=test TS_NODE_PROJECT=tsconfig.spec.json TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register --project tsconfig.spec.json 'test/*.ts'"
|
|
27
24
|
},
|
|
28
25
|
"files": [
|
|
29
26
|
"dist",
|
|
30
27
|
"src",
|
|
31
|
-
"rollup.config.js",
|
|
32
|
-
"build-dist.sh",
|
|
33
28
|
"README.md",
|
|
34
29
|
"LICENSE"
|
|
35
30
|
],
|
|
36
|
-
"main": "dist/index.js",
|
|
31
|
+
"main": "dist/src/index.js",
|
|
37
32
|
"module": "dist/esm/index.js",
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
"require": "./dist/index.js",
|
|
41
|
-
"import": "./dist/esm/index.js"
|
|
42
|
-
},
|
|
43
|
-
"./package.json": "./package.json"
|
|
44
|
-
},
|
|
33
|
+
"browser": "dist/esm/index.js",
|
|
34
|
+
"types": "dist/esm/index.d.ts",
|
|
45
35
|
"dependencies": {
|
|
46
|
-
"@
|
|
36
|
+
"@digitalbazaar/http-client": "digitalcredentials/http-client#react-native",
|
|
37
|
+
"@digitalcredentials/bnid": "^3.0.1",
|
|
47
38
|
"@digitalcredentials/did-io": "^1.0.2",
|
|
48
|
-
"@digitalcredentials/http-client": "^1.2.2",
|
|
49
39
|
"did-context": "^3.1.1",
|
|
50
40
|
"ed25519-signature-2020-context": "^1.1.0",
|
|
51
|
-
"whatwg-url": "^
|
|
41
|
+
"whatwg-url": "^14.0.0",
|
|
52
42
|
"x25519-key-agreement-2020-context": "^1.0.0"
|
|
53
43
|
},
|
|
44
|
+
"resolutions": {
|
|
45
|
+
"@typescript-eslint/typescript-estree": "^6.1.6"
|
|
46
|
+
},
|
|
54
47
|
"devDependencies": {
|
|
55
|
-
"@babel/core": "^7.16.7",
|
|
56
|
-
"@babel/plugin-transform-modules-commonjs": "^7.16.7",
|
|
57
|
-
"@babel/plugin-transform-runtime": "^7.16.7",
|
|
58
|
-
"@babel/preset-env": "^7.16.7",
|
|
59
|
-
"@babel/runtime": "^7.16.7",
|
|
60
48
|
"@digitalcredentials/ed25519-verification-key-2020": "^3.2.2",
|
|
61
49
|
"@digitalcredentials/x25519-key-agreement-key-2020": "^2.0.2",
|
|
62
|
-
"
|
|
63
|
-
"
|
|
50
|
+
"@types/chai": "^4.3.5",
|
|
51
|
+
"@types/mocha": "^10.0.1",
|
|
52
|
+
"@types/node": "^20.4.6",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
|
54
|
+
"@typescript-eslint/parser": "^5.0.0",
|
|
55
|
+
"chai": "^4.3.7",
|
|
64
56
|
"cross-env": "^7.0.3",
|
|
65
57
|
"crypto-ld": "^6.0.0",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
"karma-webpack": "^5.0.0",
|
|
76
|
-
"mocha": "^8.4.0",
|
|
77
|
-
"nyc": "^15.1.0",
|
|
78
|
-
"rimraf": "^3.0.2",
|
|
79
|
-
"rollup": "^2.62.0",
|
|
80
|
-
"sinon": "^12.0.1",
|
|
81
|
-
"standard": "^16.0.4",
|
|
82
|
-
"webpack": "^5.65.0"
|
|
58
|
+
"eslint": "^8.46.0",
|
|
59
|
+
"mocha": "^10.2.0",
|
|
60
|
+
"rimraf": "^5.0.1",
|
|
61
|
+
"ts-node": "^10.9.1",
|
|
62
|
+
"ts-standard": "^12.0.2",
|
|
63
|
+
"typescript": "5.2.2"
|
|
64
|
+
},
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public"
|
|
83
67
|
},
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
|
|
87
|
-
"
|
|
68
|
+
"mocha": {
|
|
69
|
+
"require": "ts-node/register",
|
|
70
|
+
"extension": [
|
|
71
|
+
"ts"
|
|
88
72
|
],
|
|
89
|
-
"
|
|
73
|
+
"spec": "test/**/*.ts"
|
|
90
74
|
},
|
|
91
|
-
"standard": {
|
|
75
|
+
"ts-standard": {
|
|
76
|
+
"ignore": [
|
|
77
|
+
"dist"
|
|
78
|
+
],
|
|
92
79
|
"globals": [
|
|
93
|
-
"after",
|
|
94
|
-
"afterEach",
|
|
95
|
-
"before",
|
|
96
|
-
"beforeEach",
|
|
97
|
-
"describe",
|
|
98
80
|
"it",
|
|
99
|
-
"
|
|
81
|
+
"describe",
|
|
82
|
+
"beforeEach"
|
|
100
83
|
]
|
|
101
84
|
},
|
|
102
85
|
"engines": {
|
|
103
|
-
"node": ">=
|
|
86
|
+
"node": ">=18.0"
|
|
87
|
+
},
|
|
88
|
+
"standard": {
|
|
89
|
+
"globals": [
|
|
90
|
+
"it"
|
|
91
|
+
]
|
|
104
92
|
}
|
|
105
93
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
|
2
|
+
import { httpClient } from '@digitalbazaar/http-client'
|
|
2
3
|
import * as didIo from '@digitalcredentials/did-io'
|
|
3
|
-
import ed25519Context from 'ed25519-signature-2020-context'
|
|
4
|
-
import x25519Context from 'x25519-key-agreement-2020-context'
|
|
5
|
-
import didContext from 'did-context'
|
|
4
|
+
import * as ed25519Context from 'ed25519-signature-2020-context'
|
|
5
|
+
import * as x25519Context from 'x25519-key-agreement-2020-context'
|
|
6
|
+
import * as didContext from 'did-context'
|
|
6
7
|
import { decodeSecretKeySeed } from '@digitalcredentials/bnid'
|
|
7
8
|
import { URL } from 'whatwg-url'
|
|
8
9
|
|
|
@@ -16,7 +17,7 @@ const DEFAULT_KEY_MAP = {
|
|
|
16
17
|
keyAgreement: 'X25519KeyAgreementKey2020'
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
export function didFromUrl ({ url } = {}) {
|
|
20
|
+
export function didFromUrl ({ url }: { url?: string } = {}): string {
|
|
20
21
|
if (!url) {
|
|
21
22
|
throw new TypeError('Cannot convert url to did, missing url.')
|
|
22
23
|
}
|
|
@@ -31,29 +32,37 @@ export function didFromUrl ({ url } = {}) {
|
|
|
31
32
|
throw new TypeError(`Invalid url: "${url}".`)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
let { host, pathname } = parsedUrl
|
|
36
36
|
let pathComponent = ''
|
|
37
|
-
|
|
37
|
+
|
|
38
|
+
const didJsonSuffix = '/did.json'
|
|
39
|
+
const wellKnownSuffix = '/.well-known'
|
|
40
|
+
|
|
41
|
+
if (pathname?.endsWith(didJsonSuffix)) {
|
|
42
|
+
pathname = pathname.substring(0, pathname.length - didJsonSuffix.length)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (pathname?.endsWith(wellKnownSuffix)) {
|
|
46
|
+
pathname = pathname.substring(0, pathname.length - wellKnownSuffix.length)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (pathname && pathname !== '/') {
|
|
38
50
|
pathComponent = pathname.split('/').map(encodeURIComponent).join(':')
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
return 'did:web:' + encodeURIComponent(host) + pathComponent
|
|
42
54
|
}
|
|
43
55
|
|
|
44
|
-
export function urlFromDid ({ did }
|
|
45
|
-
if (!did) {
|
|
46
|
-
throw new TypeError(
|
|
47
|
-
}
|
|
48
|
-
if (!did.startsWith('did:web:')) {
|
|
49
|
-
throw new TypeError(`DID Method not supported: "${did}".`)
|
|
56
|
+
export function urlFromDid ({ did }: { did: string | undefined }): string {
|
|
57
|
+
if (!did?.startsWith('did:web:')) {
|
|
58
|
+
throw new TypeError(`DID Method not supported: "${did ?? ''}".`)
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
const [didUrl, hashFragment] = did.split('#')
|
|
53
62
|
// eslint-disable-next-line no-unused-vars
|
|
54
63
|
// const [didResource, query] = didUrl.split('?')
|
|
55
64
|
|
|
56
|
-
// eslint-disable-next-line no-unused-vars
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
57
66
|
const [_did, _web, urlNoProtocol, ...pathFragments] = didUrl.split(':')
|
|
58
67
|
|
|
59
68
|
if (urlNoProtocol.includes('/')) {
|
|
@@ -108,8 +117,11 @@ export function urlFromDid ({ did } = {}) {
|
|
|
108
117
|
* DID Document initialized with keys, as well as the map of the corresponding
|
|
109
118
|
* key pairs (by key id).
|
|
110
119
|
*/
|
|
111
|
-
export async function initKeys (
|
|
112
|
-
|
|
120
|
+
export async function initKeys (
|
|
121
|
+
{ didDocument, cryptoLd, keyMap }:
|
|
122
|
+
{ didDocument?: object, cryptoLd?: any, keyMap?: any } = {}
|
|
123
|
+
): Promise<{ didDocument: object, keyPairs: Map<string, any> }> {
|
|
124
|
+
const doc: any = { ...didDocument }
|
|
113
125
|
if (!doc.id) {
|
|
114
126
|
throw new TypeError(
|
|
115
127
|
'DID Document "id" property is required to initialize keys.')
|
|
@@ -144,13 +156,19 @@ export async function initKeys ({ didDocument, cryptoLd, keyMap } = {}) {
|
|
|
144
156
|
}
|
|
145
157
|
|
|
146
158
|
export class DidWebResolver {
|
|
159
|
+
public cryptoLd: any
|
|
160
|
+
public keyMap: object
|
|
161
|
+
public method: string
|
|
162
|
+
public logger: any
|
|
163
|
+
|
|
147
164
|
/**
|
|
148
165
|
* @param cryptoLd {CryptoLD}
|
|
149
166
|
* @param keyMap {object}
|
|
150
167
|
* @param [logger] {object} Logger object (with .log, .error, .warn,
|
|
151
168
|
* etc methods).
|
|
152
169
|
*/
|
|
153
|
-
constructor ({ cryptoLd, keyMap = DEFAULT_KEY_MAP, logger = console }
|
|
170
|
+
constructor ({ cryptoLd, keyMap = DEFAULT_KEY_MAP, logger = console }:
|
|
171
|
+
{ cryptoLd?: any, keyMap?: object, logger?: any } = {}) {
|
|
154
172
|
this.method = 'web' // did:web:... (used for didIo resolver harness)
|
|
155
173
|
this.cryptoLd = cryptoLd
|
|
156
174
|
this.keyMap = keyMap
|
|
@@ -171,18 +189,23 @@ export class DidWebResolver {
|
|
|
171
189
|
* Either an `id` or a `url` is required:
|
|
172
190
|
* @param [id] {string} - A did:web DID. If absent, will be converted from url
|
|
173
191
|
* @param [url] {string}
|
|
192
|
+
* @param [seed] {string|Uint8Array}
|
|
174
193
|
*
|
|
175
194
|
* @param [keyMap] {object} A hashmap of key types by purpose.
|
|
176
195
|
*
|
|
196
|
+
* @param cryptoLd
|
|
177
197
|
* @parma [cryptoLd] {object} CryptoLD instance with support for supported
|
|
178
198
|
* crypto suites installed.
|
|
179
199
|
*
|
|
180
|
-
* @returns {Promise<{didDocument: object, keyPairs:
|
|
200
|
+
* @returns {Promise<{didDocument: object, keyPairs: object,
|
|
181
201
|
* methodFor: Function}>} Resolves with the generated DID Document, along
|
|
182
202
|
* with the corresponding key pairs used to generate it (for storage in a
|
|
183
203
|
* KMS).
|
|
184
204
|
*/
|
|
185
|
-
async generate (
|
|
205
|
+
async generate (
|
|
206
|
+
{ id, url, seed, keyMap, cryptoLd = this.cryptoLd }:
|
|
207
|
+
{ id?: string, url?: string, seed?: string | Uint8Array, keyMap?: any, cryptoLd?: any } = {}):
|
|
208
|
+
Promise<{ didDocument: any, keyPairs: object, methodFor: Function }> {
|
|
186
209
|
if (!id && !url) {
|
|
187
210
|
throw new TypeError('A "url" or an "id" parameter is required.')
|
|
188
211
|
}
|
|
@@ -192,7 +215,7 @@ export class DidWebResolver {
|
|
|
192
215
|
)
|
|
193
216
|
}
|
|
194
217
|
|
|
195
|
-
const did = id
|
|
218
|
+
const did = id ?? didFromUrl({ url })
|
|
196
219
|
|
|
197
220
|
if (seed) {
|
|
198
221
|
const keyPair = await _keyPairFromSecretSeed({
|
|
@@ -213,13 +236,13 @@ export class DidWebResolver {
|
|
|
213
236
|
id: did
|
|
214
237
|
}
|
|
215
238
|
|
|
216
|
-
const result = await initKeys({ didDocument, cryptoLd, keyMap })
|
|
239
|
+
const result: any = await initKeys({ didDocument, cryptoLd, keyMap })
|
|
217
240
|
const keyPairs = result.keyPairs
|
|
218
241
|
didDocument = result.didDocument
|
|
219
242
|
|
|
220
243
|
// Convenience function that returns the public/private key pair instance
|
|
221
244
|
// for a given purpose (authentication, assertionMethod, keyAgreement, etc).
|
|
222
|
-
const methodFor = ({ purpose }) => {
|
|
245
|
+
const methodFor = ({ purpose }: { purpose: string }): any => {
|
|
223
246
|
const { id: methodId } = didIo.findVerificationMethod({
|
|
224
247
|
doc: didDocument, purpose
|
|
225
248
|
})
|
|
@@ -247,8 +270,8 @@ export class DidWebResolver {
|
|
|
247
270
|
*
|
|
248
271
|
* @returns {Promise<object>} Plain parsed JSON object of the DID Document.
|
|
249
272
|
*/
|
|
250
|
-
async get ({ did, url, agent, logger = this.logger }) {
|
|
251
|
-
const didUrl = url
|
|
273
|
+
async get ({ did, url, agent, logger = this.logger }: { did?: string | undefined, url?: string | undefined, agent?: any, logger?: any }): Promise<object> {
|
|
274
|
+
const didUrl = url ?? urlFromDid({ did })
|
|
252
275
|
if (!didUrl) {
|
|
253
276
|
throw new TypeError('A DID or a URL is required.')
|
|
254
277
|
}
|
|
@@ -260,11 +283,12 @@ export class DidWebResolver {
|
|
|
260
283
|
logger.info(`Fetching "${urlAuthority}" via http client.`)
|
|
261
284
|
const result = await httpClient.get(urlAuthority, { agent })
|
|
262
285
|
didDocument = result.data
|
|
263
|
-
} catch (e) {
|
|
286
|
+
} catch (e: any) {
|
|
264
287
|
// status is HTTP status code
|
|
265
288
|
// data is JSON error from the server if available
|
|
266
289
|
const { data, status } = e
|
|
267
|
-
|
|
290
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
291
|
+
logger.error(`Http ${status ?? ''} error:`, data)
|
|
268
292
|
throw e
|
|
269
293
|
}
|
|
270
294
|
if (didDocument && keyIdFragment) {
|
|
@@ -308,14 +332,7 @@ export class DidWebResolver {
|
|
|
308
332
|
* @returns {object} Returns the public key object (obtained from the DID
|
|
309
333
|
* Document), without a `@context`.
|
|
310
334
|
*/
|
|
311
|
-
publicMethodFor ({ didDocument, purpose }
|
|
312
|
-
if (!didDocument) {
|
|
313
|
-
throw new TypeError('The "didDocument" parameter is required.')
|
|
314
|
-
}
|
|
315
|
-
if (!purpose) {
|
|
316
|
-
throw new TypeError('The "purpose" parameter is required.')
|
|
317
|
-
}
|
|
318
|
-
|
|
335
|
+
publicMethodFor ({ didDocument, purpose }: { didDocument: any, purpose: string }): any {
|
|
319
336
|
const method = didIo.findVerificationMethod({ doc: didDocument, purpose })
|
|
320
337
|
if (!method) {
|
|
321
338
|
throw new Error(`No verification method found for purpose "${purpose}"`)
|
|
@@ -332,7 +349,7 @@ export class DidWebResolver {
|
|
|
332
349
|
*
|
|
333
350
|
* @return {Promise<LDKeyPair>}
|
|
334
351
|
*/
|
|
335
|
-
async function _keyPairFromSecretSeed ({ seed, controller, cryptoLd }
|
|
352
|
+
async function _keyPairFromSecretSeed ({ seed, controller, cryptoLd }: { seed: string | Uint8Array, controller?: string, cryptoLd?: any }): Promise<any> {
|
|
336
353
|
let seedBytes
|
|
337
354
|
if (typeof seed === 'string') {
|
|
338
355
|
// Currently only supports base58 multibase / identity multihash encoding.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare module '@digitalbazaar/http-client'
|
|
2
|
+
declare module '@digitalcredentials/did-io'
|
|
3
|
+
declare module 'ed25519-signature-2020-context'
|
|
4
|
+
declare module 'x25519-key-agreement-2020-context'
|
|
5
|
+
declare module 'did-context'
|
|
6
|
+
declare module '@digitalcredentials/bnid'
|
|
7
|
+
declare module '@digitalcredentials/ed25519-verification-key-2020'
|
|
8
|
+
declare module '@digitalcredentials/x25519-key-agreement-key-2020'
|
|
9
|
+
declare module 'crypto-ld'
|
|
10
|
+
declare module 'whatwg-url'
|
|
11
|
+
declare module 'dirty-chai'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { DidWebResolver, didFromUrl, urlFromDid } from './DidWebResolver
|
|
2
|
+
import { DidWebResolver, didFromUrl, urlFromDid } from './DidWebResolver'
|
|
3
3
|
|
|
4
|
-
const driver = options => {
|
|
4
|
+
const driver = (options: { cryptoLd?: any, keyMap?: object | undefined, logger?: any } | undefined): DidWebResolver => {
|
|
5
5
|
return new DidWebResolver(options)
|
|
6
6
|
}
|
|
7
7
|
|
package/build-dist.sh
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
mkdir ./dist/esm
|
|
2
|
-
cat >dist/esm/index.js <<!EOF
|
|
3
|
-
import cjsModule from '../index.js';
|
|
4
|
-
export const driver = cjsModule.driver;
|
|
5
|
-
export const DidWebResolver = cjsModule.DidWebResolver;
|
|
6
|
-
export const didFromUrl = cjsModule.didFromUrl;
|
|
7
|
-
export const urlFromDid = cjsModule.urlFromDid;
|
|
8
|
-
!EOF
|
|
9
|
-
|
|
10
|
-
cat >dist/esm/package.json <<!EOF
|
|
11
|
-
{
|
|
12
|
-
"type": "module"
|
|
13
|
-
}
|
|
14
|
-
!EOF
|