@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 +36 -5
- package/dist/DidWebResolver.js +51 -7
- package/package.json +14 -11
- package/src/DidWebResolver.js +49 -5
- package/CHANGELOG.md +0 -39
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/
|
|
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 '@
|
|
40
|
+
from '@digitalcredentials/ed25519-verification-key-2020'
|
|
41
41
|
import { X25519KeyAgreementKey2020 }
|
|
42
|
-
from '@
|
|
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 '@
|
|
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
|
|
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',
|
package/dist/DidWebResolver.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var httpClient = require('@
|
|
6
|
-
var didIo = require('@
|
|
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
|
|
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,
|
|
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.
|
|
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
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"@
|
|
58
|
-
"@
|
|
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": {
|
package/src/DidWebResolver.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { httpClient } from '@
|
|
2
|
-
import * as didIo from '@
|
|
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
|
|
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,
|
|
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.
|