@interop/did-web-resolver 2.0.0 → 2.2.1

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/README.md CHANGED
@@ -21,7 +21,7 @@ TBD
21
21
  ## Background
22
22
 
23
23
  A `did:web` method driver for use with in-browser and server-side on Node.js
24
- with the [`did-io`](https://github.com/digitalbazaar/did-io) resolver library.
24
+ with the [`did-io`](https://github.com/digitalcredentials/did-io) resolver library.
25
25
 
26
26
  Draft spec (W3C CCG Work Item):
27
27
 
@@ -37,9 +37,9 @@ Other implementations:
37
37
 
38
38
  ```js
39
39
  import { Ed25519VerificationKey2020 }
40
- from '@digitalbazaar/ed25519-verification-key-2020'
40
+ from '@digitalcredentials/ed25519-verification-key-2020'
41
41
  import { X25519KeyAgreementKey2020 }
42
- from '@digitalbazaar/x25519-key-agreement-key-2020'
42
+ from '@digitalcredentials/x25519-key-agreement-key-2020'
43
43
  import { CryptoLD } from 'crypto-ld'
44
44
 
45
45
  import * as didWeb from '@interop/did-web-resolver'
@@ -51,16 +51,47 @@ cryptoLd.use(X25519KeyAgreementKey2020)
51
51
  const didWebDriver = didWeb.driver({ cryptoLd })
52
52
 
53
53
  // Optionally use it with the CachedResolver from did-io
54
- import {CachedResolver} from '@digitalbazaar/did-io';
54
+ import {CachedResolver} from '@digitalcredentials/did-io';
55
55
  const resolver = new CachedResolver()
56
56
  resolver.use(didWebDriver)
57
57
  ```
58
58
 
59
59
  ### Generating a new DID
60
60
 
61
+ #### Generating from seed
62
+
63
+ If you have a deterministic secret seed (created with [`did-cli`](https://github.com/digitalcredentials/did-cli),
64
+ for example) and would like to generate a `did:web` document from it:
65
+
61
66
  ```js
62
- const { didDocument, keyPairs, methodFor } = await didWebDriver.generate()
67
+ const url = 'https://example.com'
68
+ const seed = 'z1AhV1bADy7RepJ64mvH7Kk7htFNGc7EA1WA5nGzLSTWc6o'
63
69
 
70
+ const { didDocument, keyPairs, methodFor } = await didWebDriver.generate({ url, seed })
71
+ // didDocument
72
+ {
73
+ '@context': [
74
+ 'https://www.w3.org/ns/did/v1',
75
+ 'https://w3id.org/security/suites/ed25519-2020/v1',
76
+ 'https://w3id.org/security/suites/x25519-2020/v1'
77
+ ],
78
+ id: 'did:web:example.com',
79
+ assertionMethod: [{
80
+ id: 'did:web:example.com#z6MkmDMjfkjs9XPCN1LfoQQRHz1mJ8PEdiVYC66XKhj3wGyB',
81
+ type: 'Ed25519VerificationKey2020',
82
+ controller: 'did:web:example.com',
83
+ publicKeyMultibase: 'z6MkmDMjfkjs9XPCN1LfoQQRHz1mJ8PEdiVYC66XKhj3wGyB'
84
+ }]
85
+ }
86
+ ```
87
+
88
+ #### Generating new random keys
89
+
90
+ Invoking `generate()` by itself will create new keypairs for each proof purpose.
91
+
92
+ ```js
93
+ const { didDocument, keyPairs, methodFor } = await didWebDriver.generate()
94
+ // didDocument
64
95
  {
65
96
  '@context': [
66
97
  'https://www.w3.org/ns/did/v1',
@@ -2,11 +2,13 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var httpClient = require('@digitalbazaar/http-client');
6
- var didIo = require('@digitalbazaar/did-io');
5
+ var httpClient = require('@digitalcredentials/http-client');
6
+ var didIo = require('@digitalcredentials/did-io');
7
7
  var ed25519Context = require('ed25519-signature-2020-context');
8
8
  var x25519Context = require('x25519-key-agreement-2020-context');
9
9
  var didContext = require('did-context');
10
+ var bnid = require('@digitalcredentials/bnid');
11
+ var whatwgUrl = require('whatwg-url');
10
12
 
11
13
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
14
 
@@ -53,7 +55,7 @@ function didFromUrl ({ url } = {}) {
53
55
 
54
56
  let parsedUrl;
55
57
  try {
56
- parsedUrl = new URL(url);
58
+ parsedUrl = new whatwgUrl.URL(url);
57
59
  } catch (error) {
58
60
  throw new TypeError(`Invalid url: "${url}".`)
59
61
  }
@@ -87,7 +89,7 @@ function urlFromDid ({ did } = {}) {
87
89
  try {
88
90
  // URI-decode the url (in case it contained a port number,
89
91
  // for example, `did:web:localhost%3A8080`
90
- parsedUrl = new URL('https://' + decodeURIComponent(urlNoProtocol));
92
+ parsedUrl = new whatwgUrl.URL('https://' + decodeURIComponent(urlNoProtocol));
91
93
  } catch (error) {
92
94
  throw new TypeError(`Cannot construct url from did: "${did}".`)
93
95
  }
@@ -132,7 +134,7 @@ function urlFromDid ({ did } = {}) {
132
134
  * DID Document initialized with keys, as well as the map of the corresponding
133
135
  * key pairs (by key id).
134
136
  */
135
- async function initKeys ({ didDocument, cryptoLd, keyMap = {} } = {}) {
137
+ async function initKeys ({ didDocument, cryptoLd, keyMap } = {}) {
136
138
  const doc = { ...didDocument };
137
139
  if (!doc.id) {
138
140
  throw new TypeError(
@@ -196,7 +198,7 @@ class DidWebResolver {
196
198
  * @param [id] {string} - A did:web DID. If absent, will be converted from url
197
199
  * @param [url] {string}
198
200
  *
199
- * @param [keyMap=DEFAULT_KEY_MAP] {object} A hashmap of key types by purpose.
201
+ * @param [keyMap] {object} A hashmap of key types by purpose.
200
202
  *
201
203
  * @parma [cryptoLd] {object} CryptoLD instance with support for supported
202
204
  * crypto suites installed.
@@ -206,9 +208,27 @@ class DidWebResolver {
206
208
  * with the corresponding key pairs used to generate it (for storage in a
207
209
  * KMS).
208
210
  */
209
- async generate ({ id, url, keyMap = this.keyMap, cryptoLd = this.cryptoLd } = {}) {
211
+ async generate ({ id, url, seed, keyMap, cryptoLd = this.cryptoLd } = {}) {
212
+ if (!id && !url) {
213
+ throw new TypeError('A "url" or an "id" parameter is required.')
214
+ }
215
+ if (seed && keyMap) {
216
+ throw new TypeError(
217
+ 'Either a "seed" or a "keyMap" param must be provided, but not both.'
218
+ )
219
+ }
220
+
210
221
  const did = id || didFromUrl({ url });
211
222
 
223
+ if (seed) {
224
+ const keyPair = await _keyPairFromSecretSeed({
225
+ seed, controller: did, cryptoLd
226
+ });
227
+ keyMap = { assertionMethod: keyPair };
228
+ } else {
229
+ keyMap = keyMap || this.keyMap;
230
+ }
231
+
212
232
  // Compose the DID Document
213
233
  let didDocument = {
214
234
  '@context': [
@@ -330,6 +350,30 @@ class DidWebResolver {
330
350
  }
331
351
  }
332
352
 
353
+ /**
354
+ * @param options {object}
355
+ * @param options.seed {string|Uint8Array}
356
+ * @param controller {string}
357
+ * @param cryptoLd {object}
358
+ *
359
+ * @return {Promise<LDKeyPair>}
360
+ */
361
+ async function _keyPairFromSecretSeed ({ seed, controller, cryptoLd } = {}) {
362
+ let seedBytes;
363
+ if (typeof seed === 'string') {
364
+ // Currently only supports base58 multibase / identity multihash encoding.
365
+ if (!seed.startsWith('z1A')) {
366
+ throw new TypeError('"seed" parameter must be a multibase/multihash encoded string, or a Uint8Array.')
367
+ }
368
+ seedBytes = bnid.decodeSecretKeySeed({ secretKeySeed: seed });
369
+ } else {
370
+ seedBytes = new Uint8Array(seed);
371
+ }
372
+ return cryptoLd.generate({
373
+ controller, seed: seedBytes, type: 'Ed25519VerificationKey2020'
374
+ })
375
+ }
376
+
333
377
  exports.DidWebResolver = DidWebResolver;
334
378
  exports.didFromUrl = didFromUrl;
335
379
  exports.initKeys = initKeys;
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": "2.0.0",
4
+ "version": "2.2.1",
5
5
  "author": {
6
6
  "name": "Dmitri Zagidulin",
7
7
  "url": "https://github.com/dmitrizagidulin/"
@@ -39,14 +39,17 @@
39
39
  ".": {
40
40
  "require": "./dist/index.js",
41
41
  "import": "./dist/esm/index.js"
42
- }
42
+ },
43
+ "./package.json": "./package.json"
43
44
  },
44
45
  "dependencies": {
45
- "@digitalbazaar/did-io": "digitalbazaar/did-io#noesm",
46
- "@digitalbazaar/http-client": "digitalbazaar/http-client#noesm",
47
- "did-context": "digitalbazaar/did-context#nofs",
46
+ "@digitalcredentials/bnid": "^2.1.1",
47
+ "@digitalcredentials/did-io": "^1.0.2",
48
+ "@digitalcredentials/http-client": "^1.2.2",
49
+ "did-context": "^3.1.1",
48
50
  "ed25519-signature-2020-context": "^1.1.0",
49
- "x25519-key-agreement-2020-context": "digitalbazaar/x25519-key-agreement-2020-context#nofs"
51
+ "whatwg-url": "^11.0.0",
52
+ "x25519-key-agreement-2020-context": "^1.0.0"
50
53
  },
51
54
  "devDependencies": {
52
55
  "@babel/core": "^7.16.7",
@@ -54,14 +57,14 @@
54
57
  "@babel/plugin-transform-runtime": "^7.16.7",
55
58
  "@babel/preset-env": "^7.16.7",
56
59
  "@babel/runtime": "^7.16.7",
57
- "@digitalbazaar/ed25519-verification-key-2020": "^3.2.0",
58
- "@digitalbazaar/x25519-key-agreement-key-2020": "^2.0.0",
60
+ "@digitalcredentials/ed25519-verification-key-2020": "^3.2.2",
61
+ "@digitalcredentials/x25519-key-agreement-key-2020": "^2.0.2",
59
62
  "babel-loader": "^8.2.3",
60
63
  "chai": "^4.3.4",
61
64
  "cross-env": "^7.0.3",
62
65
  "crypto-ld": "^6.0.0",
63
- "esm": "^3.2.25",
64
66
  "dirty-chai": "^2.0.1",
67
+ "esm": "^3.2.25",
65
68
  "karma": "^6.3.9",
66
69
  "karma-babel-preprocessor": "^8.0.1",
67
70
  "karma-chai": "^0.1.0",
@@ -72,10 +75,10 @@
72
75
  "karma-webpack": "^5.0.0",
73
76
  "mocha": "^8.4.0",
74
77
  "nyc": "^15.1.0",
75
- "sinon": "^12.0.1",
76
- "standard": "^16.0.4",
77
78
  "rimraf": "^3.0.2",
78
79
  "rollup": "^2.62.0",
80
+ "sinon": "^12.0.1",
81
+ "standard": "^16.0.4",
79
82
  "webpack": "^5.65.0"
80
83
  },
81
84
  "nyc": {
@@ -1,8 +1,10 @@
1
- import { httpClient } from '@digitalbazaar/http-client'
2
- import * as didIo from '@digitalbazaar/did-io'
1
+ import { httpClient } from '@digitalcredentials/http-client'
2
+ import * as didIo from '@digitalcredentials/did-io'
3
3
  import ed25519Context from 'ed25519-signature-2020-context'
4
4
  import x25519Context from 'x25519-key-agreement-2020-context'
5
5
  import didContext from 'did-context'
6
+ import { decodeSecretKeySeed } from '@digitalcredentials/bnid'
7
+ import { URL } from 'whatwg-url'
6
8
 
7
9
  const { VERIFICATION_RELATIONSHIPS } = didIo
8
10
 
@@ -103,7 +105,7 @@ export function urlFromDid ({ did } = {}) {
103
105
  * DID Document initialized with keys, as well as the map of the corresponding
104
106
  * key pairs (by key id).
105
107
  */
106
- export async function initKeys ({ didDocument, cryptoLd, keyMap = {} } = {}) {
108
+ export async function initKeys ({ didDocument, cryptoLd, keyMap } = {}) {
107
109
  const doc = { ...didDocument }
108
110
  if (!doc.id) {
109
111
  throw new TypeError(
@@ -167,7 +169,7 @@ export class DidWebResolver {
167
169
  * @param [id] {string} - A did:web DID. If absent, will be converted from url
168
170
  * @param [url] {string}
169
171
  *
170
- * @param [keyMap=DEFAULT_KEY_MAP] {object} A hashmap of key types by purpose.
172
+ * @param [keyMap] {object} A hashmap of key types by purpose.
171
173
  *
172
174
  * @parma [cryptoLd] {object} CryptoLD instance with support for supported
173
175
  * crypto suites installed.
@@ -177,9 +179,27 @@ export class DidWebResolver {
177
179
  * with the corresponding key pairs used to generate it (for storage in a
178
180
  * KMS).
179
181
  */
180
- async generate ({ id, url, keyMap = this.keyMap, cryptoLd = this.cryptoLd } = {}) {
182
+ async generate ({ id, url, seed, keyMap, cryptoLd = this.cryptoLd } = {}) {
183
+ if (!id && !url) {
184
+ throw new TypeError('A "url" or an "id" parameter is required.')
185
+ }
186
+ if (seed && keyMap) {
187
+ throw new TypeError(
188
+ 'Either a "seed" or a "keyMap" param must be provided, but not both.'
189
+ )
190
+ }
191
+
181
192
  const did = id || didFromUrl({ url })
182
193
 
194
+ if (seed) {
195
+ const keyPair = await _keyPairFromSecretSeed({
196
+ seed, controller: did, cryptoLd
197
+ })
198
+ keyMap = { assertionMethod: keyPair }
199
+ } else {
200
+ keyMap = keyMap || this.keyMap
201
+ }
202
+
183
203
  // Compose the DID Document
184
204
  let didDocument = {
185
205
  '@context': [
@@ -300,3 +320,27 @@ export class DidWebResolver {
300
320
  return method
301
321
  }
302
322
  }
323
+
324
+ /**
325
+ * @param options {object}
326
+ * @param options.seed {string|Uint8Array}
327
+ * @param controller {string}
328
+ * @param cryptoLd {object}
329
+ *
330
+ * @return {Promise<LDKeyPair>}
331
+ */
332
+ async function _keyPairFromSecretSeed ({ seed, controller, cryptoLd } = {}) {
333
+ let seedBytes
334
+ if (typeof seed === 'string') {
335
+ // Currently only supports base58 multibase / identity multihash encoding.
336
+ if (!seed.startsWith('z1A')) {
337
+ throw new TypeError('"seed" parameter must be a multibase/multihash encoded string, or a Uint8Array.')
338
+ }
339
+ seedBytes = decodeSecretKeySeed({ secretKeySeed: seed })
340
+ } else {
341
+ seedBytes = new Uint8Array(seed)
342
+ }
343
+ return cryptoLd.generate({
344
+ controller, seed: seedBytes, type: 'Ed25519VerificationKey2020'
345
+ })
346
+ }
package/CHANGELOG.md DELETED
@@ -1,39 +0,0 @@
1
- # did-web-driver ChangeLog
2
-
3
- ## 2.0.0 - 2022-01-01
4
-
5
- ### Changed
6
- - Use rollup for build-time transpile instead of esm.
7
- - Use "no ESM" branches for all other deps.
8
- - `.get()` now also resolves keys (to match other did-io drivers).
9
- - **BREAKING**: Update ed25519 and X25519 dependencies to latest. You will have
10
- to re-generate your `did:web` DID documents for this version, as the
11
- key serialization formats have changed.
12
-
13
- ## 1.1.0 - 2021-04-25
14
-
15
- ### Added
16
- - Add `didWebDriver.publicMethodFor()`.
17
-
18
- ## 1.0.1 - 2021-04-25
19
-
20
- ### Fixed
21
- - Fix handling of hash fragments by `urlFromDid()`.
22
- - Add logger to constructor.
23
-
24
- ## 1.0.0 - 2021-04-24
25
-
26
- ### Changed
27
- - **BREAKING** Update to latest DID Core context
28
- - **BREAKING** Update to use crypto-ld v5 API, latest crypto suites
29
- - Add support for X25519KeyAgreementKey suite
30
-
31
- ## 0.2.0 - 2020-08-01
32
-
33
- ### Changed
34
- - **BREAKING**: Update to use crypto-ld v4 API
35
-
36
- ## 0.0.1
37
-
38
- ### Added
39
- - Initial implementation.