@interop/wallet-core 0.16.0 → 0.18.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/README.md +13 -13
- package/dist/clients/index.d.ts +4 -3
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +3 -2
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/policy.d.ts +3 -3
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +1 -1
- package/dist/clients/revocation.d.ts +18 -15
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +42 -26
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +46 -24
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +106 -48
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/descriptors/refresh.d.ts +3 -1
- package/dist/descriptors/refresh.d.ts.map +1 -1
- package/dist/descriptors/refresh.js +3 -1
- package/dist/descriptors/refresh.js.map +1 -1
- package/dist/display/alignment.d.ts +8 -2
- package/dist/display/alignment.d.ts.map +1 -1
- package/dist/display/alignment.js +11 -8
- package/dist/display/alignment.js.map +1 -1
- package/dist/display/displayFields.d.ts +6 -2
- package/dist/display/displayFields.d.ts.map +1 -1
- package/dist/display/displayFields.js.map +1 -1
- package/dist/display/evidence.d.ts +9 -3
- package/dist/display/evidence.d.ts.map +1 -1
- package/dist/display/evidence.js +3 -1
- package/dist/display/evidence.js.map +1 -1
- package/dist/display/index.d.ts +1 -1
- package/dist/display/index.d.ts.map +1 -1
- package/dist/display/index.js +1 -1
- package/dist/display/index.js.map +1 -1
- package/dist/display/issuer.d.ts +12 -4
- package/dist/display/issuer.d.ts.map +1 -1
- package/dist/display/issuer.js.map +1 -1
- package/dist/display/obv3.d.ts +7 -2
- package/dist/display/obv3.d.ts.map +1 -1
- package/dist/display/obv3.js +14 -24
- package/dist/display/obv3.js.map +1 -1
- package/dist/display/parse.d.ts +6 -2
- package/dist/display/parse.d.ts.map +1 -1
- package/dist/display/parse.js +6 -2
- package/dist/display/parse.js.map +1 -1
- package/dist/display/subject.d.ts +4 -0
- package/dist/display/subject.d.ts.map +1 -1
- package/dist/display/subject.js +12 -10
- package/dist/display/subject.js.map +1 -1
- package/dist/display/text.d.ts +11 -0
- package/dist/display/text.d.ts.map +1 -1
- package/dist/display/text.js +20 -4
- package/dist/display/text.js.map +1 -1
- package/dist/display/types.js +1 -1
- package/dist/display/types.js.map +1 -1
- package/dist/display/validity.js +4 -4
- package/dist/display/validity.js.map +1 -1
- package/dist/display/verificationView.d.ts +21 -7
- package/dist/display/verificationView.d.ts.map +1 -1
- package/dist/display/verificationView.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts +21 -19
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +98 -34
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/enrollment/index.d.ts +1 -1
- package/dist/enrollment/index.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/keys/clientKeyRecord.d.ts +19 -17
- package/dist/keys/clientKeyRecord.d.ts.map +1 -1
- package/dist/keys/clientKeyRecord.js +77 -41
- package/dist/keys/clientKeyRecord.js.map +1 -1
- package/dist/keys/index.d.ts +19 -17
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +16 -14
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterStore.d.ts +3 -3
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +13 -13
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/keys/userKey.d.ts +43 -0
- package/dist/keys/userKey.d.ts.map +1 -0
- package/dist/keys/{puk.js → userKey.js} +23 -21
- package/dist/keys/userKey.js.map +1 -0
- package/dist/keys/{pukCascade.d.ts → userKeyCascade.d.ts} +69 -69
- package/dist/keys/userKeyCascade.d.ts.map +1 -0
- package/dist/keys/{pukCascade.js → userKeyCascade.js} +77 -75
- package/dist/keys/userKeyCascade.js.map +1 -0
- package/dist/keys/{pukRoster.d.ts → userKeyRoster.d.ts} +141 -64
- package/dist/keys/userKeyRoster.d.ts.map +1 -0
- package/dist/keys/{pukRoster.js → userKeyRoster.js} +200 -72
- package/dist/keys/userKeyRoster.js.map +1 -0
- package/dist/recovery/index.d.ts +1 -1
- package/dist/recovery/index.js +1 -1
- package/dist/recovery/recoveryCode.d.ts +1 -1
- package/dist/recovery/recoveryCode.js +6 -6
- package/dist/recovery/recoveryRecord.d.ts +1 -1
- package/dist/recovery/recoveryWebvh.d.ts +1 -1
- package/dist/recovery/recoveryWebvh.js +1 -1
- package/dist/request/classify.d.ts +15 -1
- package/dist/request/classify.d.ts.map +1 -1
- package/dist/request/classify.js +38 -14
- package/dist/request/classify.js.map +1 -1
- package/dist/request/composeVp.d.ts.map +1 -1
- package/dist/request/composeVp.js +10 -3
- package/dist/request/composeVp.js.map +1 -1
- package/dist/request/matching.d.ts +6 -0
- package/dist/request/matching.d.ts.map +1 -1
- package/dist/request/matching.js +33 -8
- package/dist/request/matching.js.map +1 -1
- package/dist/request/parse.d.ts +5 -2
- package/dist/request/parse.d.ts.map +1 -1
- package/dist/request/parse.js +30 -5
- package/dist/request/parse.js.map +1 -1
- package/dist/request/presentationSuite.d.ts.map +1 -1
- package/dist/request/presentationSuite.js +6 -2
- package/dist/request/presentationSuite.js.map +1 -1
- package/dist/request/processRequest.js +1 -1
- package/dist/request/processRequest.js.map +1 -1
- package/dist/space/activity.d.ts +22 -8
- package/dist/space/activity.d.ts.map +1 -1
- package/dist/space/activity.js +19 -7
- package/dist/space/activity.js.map +1 -1
- package/dist/space/collections.d.ts +33 -21
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +34 -22
- package/dist/space/collections.js.map +1 -1
- package/dist/space/index.d.ts +2 -2
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +2 -2
- package/dist/space/index.js.map +1 -1
- package/dist/space/wasLink.d.ts +6 -2
- package/dist/space/wasLink.d.ts.map +1 -1
- package/dist/space/wasLink.js +5 -2
- package/dist/space/wasLink.js.map +1 -1
- package/dist/sync/contactsConflict.d.ts +1 -1
- package/dist/sync/contactsConflict.js +1 -1
- package/dist/sync/engine.d.ts +33 -11
- package/dist/sync/engine.d.ts.map +1 -1
- package/dist/sync/engine.js +4 -3
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/pull.d.ts +5 -3
- package/dist/sync/pull.d.ts.map +1 -1
- package/dist/sync/pull.js +34 -10
- package/dist/sync/pull.js.map +1 -1
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +24 -8
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/types.d.ts +30 -6
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/webvh/didWebvh.d.ts +29 -1
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +46 -11
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +1 -1
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +1 -1
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts +19 -0
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +37 -1
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +11 -3
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +83 -14
- package/dist/webvh/revokeClient.js.map +1 -1
- package/package.json +3 -3
- package/dist/keys/puk.d.ts +0 -42
- package/dist/keys/puk.d.ts.map +0 -1
- package/dist/keys/puk.js.map +0 -1
- package/dist/keys/pukCascade.d.ts.map +0 -1
- package/dist/keys/pukCascade.js.map +0 -1
- package/dist/keys/pukRoster.d.ts.map +0 -1
- package/dist/keys/pukRoster.js.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { base64urlnopad } from '@scure/base';
|
|
2
|
+
import { multibaseDecode, MULTICODEC_X25519_PUB_HEADER } from '@interop/x25519-key-agreement-key';
|
|
2
3
|
import { agentsFromSeed } from '../identity/agents.js';
|
|
3
4
|
import { enrollWebvhClient, mintClientWebvhUpdateKeys, updateKeyMultibase } from '../webvh/didWebvh.js';
|
|
4
5
|
import { clientSigningKeyMultibase, isWebvhDid, webvhZcapClient } from '../webvh/zcap.js';
|
|
5
6
|
import { AccountLogMissingError, verifyAccountLog } from '../webvh/verifyLog.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { addUserKeyRosterRecipient } from '../keys/userKeyRoster.js';
|
|
8
|
+
import { readUserKeyRoster, rosterRecipientKid } from '../keys/userKeyRoster.js';
|
|
9
|
+
import { userKeyRosterDescriptorStore } from '../keys/rosterStore.js';
|
|
9
10
|
import { CONNECT_CODE_PREFIX } from './connectCode.js';
|
|
10
11
|
/**
|
|
11
12
|
* The connect-code payload version this build mints and accepts.
|
|
@@ -29,6 +30,48 @@ export class EnrollmentPendingError extends Error {
|
|
|
29
30
|
*/
|
|
30
31
|
const ED25519_MULTIBASE_PREFIX = 'z6Mk';
|
|
31
32
|
const X25519_MULTIBASE_PREFIX = 'z6LS';
|
|
33
|
+
/**
|
|
34
|
+
* The multicodec varint header of an `ed25519-pub` value, the registry
|
|
35
|
+
* constant the `z6Mk` prefix renders. The X25519 counterpart is imported from
|
|
36
|
+
* the key suite that owns it; there is no exported Ed25519 equivalent.
|
|
37
|
+
*/
|
|
38
|
+
const MULTICODEC_ED25519_PUB_HEADER = new Uint8Array([0xed, 0x01]);
|
|
39
|
+
/**
|
|
40
|
+
* The byte length of both public key types a connect code carries.
|
|
41
|
+
*/
|
|
42
|
+
const PUBLIC_KEY_BYTES = 32;
|
|
43
|
+
/**
|
|
44
|
+
* Validates one connect-code key all the way down to its bytes: the multibase
|
|
45
|
+
* prefix, a real base58btc decode, the multicodec header, and the key length.
|
|
46
|
+
* The prefix alone is worth nothing here -- these keys are signed into an
|
|
47
|
+
* append-only did:webvh log, where a key that only LOOKS like a multibase is
|
|
48
|
+
* published forever.
|
|
49
|
+
*
|
|
50
|
+
* @param options {object}
|
|
51
|
+
* @param options.value {unknown} the payload member
|
|
52
|
+
* @param options.prefix {string} the expected multibase prefix
|
|
53
|
+
* @param options.header {Uint8Array} the expected multicodec header bytes
|
|
54
|
+
* @param options.name {string} the key's name, for the error message
|
|
55
|
+
* @returns {string} the key, verbatim
|
|
56
|
+
*/
|
|
57
|
+
function requireConnectCodeKey({ value, prefix, header, name }) {
|
|
58
|
+
if (typeof value !== 'string' || !value.startsWith(prefix)) {
|
|
59
|
+
throw new Error(`The connect code carries a malformed ${name}.`);
|
|
60
|
+
}
|
|
61
|
+
let bytes;
|
|
62
|
+
try {
|
|
63
|
+
bytes = multibaseDecode(header, value);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
throw new Error(`The connect code carries a malformed ${name}.`, {
|
|
67
|
+
cause: err
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (bytes.length !== PUBLIC_KEY_BYTES) {
|
|
71
|
+
throw new Error(`The connect code carries a malformed ${name}.`);
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
32
75
|
/**
|
|
33
76
|
* Encodes an enrollment request as a connect code.
|
|
34
77
|
*
|
|
@@ -42,9 +85,11 @@ export function encodeEnrollmentRequest({ request }) {
|
|
|
42
85
|
}
|
|
43
86
|
/**
|
|
44
87
|
* Parses and validates a connect code: the prefix, the payload version, and
|
|
45
|
-
*
|
|
46
|
-
* X25519 for the key-agreement key). Throws on anything malformed -- a
|
|
47
|
-
* is typed or scanned, so a clear refusal beats a half-parsed ceremony
|
|
88
|
+
* each key decoded to its bytes (Ed25519 multibase for the signing and update
|
|
89
|
+
* keys, X25519 for the key-agreement key). Throws on anything malformed -- a
|
|
90
|
+
* code is typed or scanned, so a clear refusal beats a half-parsed ceremony,
|
|
91
|
+
* and the approving client signs these keys into an append-only log where a
|
|
92
|
+
* corrupted one would be published permanently.
|
|
48
93
|
*
|
|
49
94
|
* @param options {object}
|
|
50
95
|
* @param options.code {string} the pasted/scanned connect code
|
|
@@ -69,17 +114,31 @@ export function parseEnrollmentRequest({ code }) {
|
|
|
69
114
|
if (v !== CONNECT_CODE_VERSION) {
|
|
70
115
|
throw new Error(`Unsupported connect code version "${String(v)}".`);
|
|
71
116
|
}
|
|
72
|
-
const requireKey = (value, prefix, name) => {
|
|
73
|
-
if (typeof value !== 'string' || !value.startsWith(prefix)) {
|
|
74
|
-
throw new Error(`The connect code carries a malformed ${name}.`);
|
|
75
|
-
}
|
|
76
|
-
return value;
|
|
77
|
-
};
|
|
78
117
|
return {
|
|
79
|
-
signingKeyMultibase:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
118
|
+
signingKeyMultibase: requireConnectCodeKey({
|
|
119
|
+
value: signingKeyMultibase,
|
|
120
|
+
prefix: ED25519_MULTIBASE_PREFIX,
|
|
121
|
+
header: MULTICODEC_ED25519_PUB_HEADER,
|
|
122
|
+
name: 'signing key'
|
|
123
|
+
}),
|
|
124
|
+
keyAgreementKeyMultibase: requireConnectCodeKey({
|
|
125
|
+
value: keyAgreementKeyMultibase,
|
|
126
|
+
prefix: X25519_MULTIBASE_PREFIX,
|
|
127
|
+
header: MULTICODEC_X25519_PUB_HEADER,
|
|
128
|
+
name: 'key-agreement key'
|
|
129
|
+
}),
|
|
130
|
+
updateKeyMultibase: requireConnectCodeKey({
|
|
131
|
+
value: updateKey,
|
|
132
|
+
prefix: ED25519_MULTIBASE_PREFIX,
|
|
133
|
+
header: MULTICODEC_ED25519_PUB_HEADER,
|
|
134
|
+
name: 'update key'
|
|
135
|
+
}),
|
|
136
|
+
stagedUpdateKeyMultibase: requireConnectCodeKey({
|
|
137
|
+
value: stagedUpdateKeyMultibase,
|
|
138
|
+
prefix: ED25519_MULTIBASE_PREFIX,
|
|
139
|
+
header: MULTICODEC_ED25519_PUB_HEADER,
|
|
140
|
+
name: 'staged update key'
|
|
141
|
+
})
|
|
83
142
|
};
|
|
84
143
|
}
|
|
85
144
|
/**
|
|
@@ -148,8 +207,8 @@ export async function mintEnrollmentRequest() {
|
|
|
148
207
|
};
|
|
149
208
|
}
|
|
150
209
|
/**
|
|
151
|
-
* ENROLLING CLIENT: the whole approval, in the push order -- the
|
|
152
|
-
* into the roster first (escrow: every epoch, so the new client reads
|
|
210
|
+
* ENROLLING CLIENT: the whole approval, in the push order -- the user key
|
|
211
|
+
* wrapped into the roster first (escrow: every epoch, so the new client reads
|
|
153
212
|
* pre-enrollment history), then the two log entries. Quorum-of-one: this
|
|
154
213
|
* client's own update key signs both entries. Idempotent at every stage, so
|
|
155
214
|
* re-approving the same code after any tear converges.
|
|
@@ -161,19 +220,19 @@ export async function mintEnrollmentRequest() {
|
|
|
161
220
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} the approving
|
|
162
221
|
* client's own (identity) key-agreement key, unwrapping each epoch for
|
|
163
222
|
* re-wrapping
|
|
164
|
-
* @param options.
|
|
165
|
-
* `key-map/
|
|
223
|
+
* @param options.userKeyRosterStore {EncryptionDescriptorStore} the account's
|
|
224
|
+
* `key-map/user-key.json` descriptor store
|
|
166
225
|
* @param options.idStore {WebvhIdStore} the account's `id` collection
|
|
167
226
|
* @returns {Promise<object>} the account's did:webvh, plus the enrollee's
|
|
168
227
|
* own identity as this call already knows it: its did:key and its signing-key
|
|
169
228
|
* multibase (the key a label or a listing row is filed under), so the caller
|
|
170
229
|
* needs no second parse of the connect code
|
|
171
230
|
*/
|
|
172
|
-
export async function approveEnrollment({ request, clientWebvhKeys, clientKeyAgreementKey,
|
|
231
|
+
export async function approveEnrollment({ request, clientWebvhKeys, clientKeyAgreementKey, userKeyRosterStore, idStore }) {
|
|
173
232
|
// Decryption material before authorization: the wrap lands first, so no
|
|
174
233
|
// enrolled client is ever authorized but blind.
|
|
175
|
-
await
|
|
176
|
-
store:
|
|
234
|
+
await addUserKeyRosterRecipient({
|
|
235
|
+
store: userKeyRosterStore,
|
|
177
236
|
recipient: {
|
|
178
237
|
id: enrollmentRecipientKid({ request }),
|
|
179
238
|
publicKeyMultibase: request.keyAgreementKeyMultibase
|
|
@@ -195,12 +254,12 @@ export async function approveEnrollment({ request, clientWebvhKeys, clientKeyAgr
|
|
|
195
254
|
* ENROLLEE, step two (after the other client approves): verifies the
|
|
196
255
|
* enrollment from the world-readable log and performs this client's first
|
|
197
256
|
* roster read -- signed with its just-published `<did:webvh>#<multibase>`
|
|
198
|
-
* key -- to obtain the
|
|
257
|
+
* key -- to obtain the user key.
|
|
199
258
|
*
|
|
200
259
|
* The portable core of the completion step: the caller supplies the account
|
|
201
260
|
* pointer (from its own keyring lookup) and persists what comes back -- the
|
|
202
|
-
*
|
|
203
|
-
* layer. After that, an ordinary unlock finds an enrolled client.
|
|
261
|
+
* user key, the roster epoch to pin, and the key set itself -- under its own
|
|
262
|
+
* unlock layer. After that, an ordinary unlock finds an enrolled client.
|
|
204
263
|
*
|
|
205
264
|
* Throws `EnrollmentPendingError` while the add entry is not published yet
|
|
206
265
|
* (complete again once the other client finishes); any integrity failure
|
|
@@ -213,7 +272,7 @@ export async function approveEnrollment({ request, clientWebvhKeys, clientKeyAgr
|
|
|
213
272
|
* `mintEnrollmentRequest`
|
|
214
273
|
* @param options.pointer {AccountPointer} the account pointer the enrollee's
|
|
215
274
|
* keyring lookup recovered
|
|
216
|
-
* @returns {Promise<{
|
|
275
|
+
* @returns {Promise<{ userKey: UserKey, latestEpochId: string }>}
|
|
217
276
|
*/
|
|
218
277
|
export async function completeEnrollmentCore({ clientSeed, webvhUpdateKeys, pointer }) {
|
|
219
278
|
const did = pointer.did;
|
|
@@ -251,22 +310,27 @@ export async function completeEnrollmentCore({ clientSeed, webvhUpdateKeys, poin
|
|
|
251
310
|
throw new EnrollmentPendingError();
|
|
252
311
|
}
|
|
253
312
|
// The first roster read: signed with the `<did:webvh>#<multibase>` keyId
|
|
254
|
-
// the add entry just published, unwrapping the
|
|
255
|
-
// escrowed to this client's key-agreement key.
|
|
313
|
+
// the add entry just published, unwrapping the user key the enrolling client
|
|
314
|
+
// escrowed to this client's key-agreement key. The verified document just
|
|
315
|
+
// resolved above is what the roster's epoch-configuration signature is
|
|
316
|
+
// checked against -- a first read adopts whatever epoch the roster serves,
|
|
317
|
+
// so it must trace to a key the document backs, not to the served
|
|
318
|
+
// descriptor's own MAC.
|
|
256
319
|
const zcapClient = webvhZcapClient({ keyAgent, did });
|
|
257
|
-
const store =
|
|
320
|
+
const store = userKeyRosterDescriptorStore({
|
|
258
321
|
storageServerUrl: pointer.host,
|
|
259
322
|
zcapClient,
|
|
260
323
|
spaceId: pointer.spaceId
|
|
261
324
|
});
|
|
262
|
-
const read = await
|
|
325
|
+
const read = await readUserKeyRoster({
|
|
263
326
|
store,
|
|
264
|
-
clientKeyAgreementKey: keyAgreementKey
|
|
327
|
+
clientKeyAgreementKey: keyAgreementKey,
|
|
328
|
+
document: verified.doc
|
|
265
329
|
});
|
|
266
330
|
if (!read) {
|
|
267
|
-
throw new Error('The account has no
|
|
331
|
+
throw new Error('The account has no user key roster; it must finish provisioning before ' +
|
|
268
332
|
'a client can be enrolled.');
|
|
269
333
|
}
|
|
270
|
-
return {
|
|
334
|
+
return { userKey: read.userKey, latestEpochId: read.latestEpochId };
|
|
271
335
|
}
|
|
272
336
|
//# sourceMappingURL=enrollment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../src/enrollment/enrollment.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,sBAAsB,CAAA;AAM7B,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,eAAe,EAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../src/enrollment/enrollment.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - `approveEnrollment` -- the enrolling client's half, in the push order
|
|
15
15
|
* (roster wrap, then the two did:webvh log entries).
|
|
16
16
|
* - `completeEnrollmentCore` -- the enrollee's half: verify from the published
|
|
17
|
-
* log, read the roster, hand back the
|
|
17
|
+
* log, read the roster, hand back the user key and the epoch to pin. Persisting
|
|
18
18
|
* the key set stays with the caller's own unlock layer.
|
|
19
19
|
*/
|
|
20
20
|
export { approveEnrollment, completeEnrollmentCore, encodeEnrollmentRequest, EnrollmentPendingError, enrollmentClientDid, enrollmentRecipientKid, mintEnrollmentRequest, parseEnrollmentRequest } from './enrollment.js';
|
package/dist/enrollment/index.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* - `approveEnrollment` -- the enrolling client's half, in the push order
|
|
15
15
|
* (roster wrap, then the two did:webvh log entries).
|
|
16
16
|
* - `completeEnrollmentCore` -- the enrollee's half: verify from the published
|
|
17
|
-
* log, read the roster, hand back the
|
|
17
|
+
* log, read the roster, hand back the user key and the epoch to pin. Persisting
|
|
18
18
|
* the key set stays with the caller's own unlock layer.
|
|
19
19
|
*/
|
|
20
20
|
export { approveEnrollment, completeEnrollmentCore, encodeEnrollmentRequest, EnrollmentPendingError, enrollmentClientDid, enrollmentRecipientKid, mintEnrollmentRequest, parseEnrollmentRequest } from './enrollment.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* - `@interop/wallet-core/webvh` -- the account's did:webvh identity: the
|
|
20
20
|
* hosted DID log, its per-client update-key rotation, the client enrollment
|
|
21
21
|
* entries, and ZCap signing under the did:webvh verification-method id.
|
|
22
|
-
* - `@interop/wallet-core/keys` -- the
|
|
23
|
-
* `key-map/
|
|
22
|
+
* - `@interop/wallet-core/keys` -- the user key and its
|
|
23
|
+
* `key-map/user-key.json` wrap-set roster.
|
|
24
24
|
* - `@interop/wallet-core/descriptors` -- collection encryption-descriptor
|
|
25
25
|
* acquisition (fetch / cache / offline fallback) and the unknown-epoch
|
|
26
26
|
* refresh policy, including a self-refreshing EDV document cipher.
|
package/dist/index.js
CHANGED
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
* - `@interop/wallet-core/webvh` -- the account's did:webvh identity: the
|
|
20
20
|
* hosted DID log, its per-client update-key rotation, the client enrollment
|
|
21
21
|
* entries, and ZCap signing under the did:webvh verification-method id.
|
|
22
|
-
* - `@interop/wallet-core/keys` -- the
|
|
23
|
-
* `key-map/
|
|
22
|
+
* - `@interop/wallet-core/keys` -- the user key and its
|
|
23
|
+
* `key-map/user-key.json` wrap-set roster.
|
|
24
24
|
* - `@interop/wallet-core/descriptors` -- collection encryption-descriptor
|
|
25
25
|
* acquisition (fetch / cache / offline fallback) and the unknown-epoch
|
|
26
26
|
* refresh policy, including a self-refreshing EDV document cipher.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import type { ClientWebvhUpdateKeys } from '../webvh/didWebvh.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { UserKey } from './userKey.js';
|
|
3
3
|
/**
|
|
4
4
|
* A client-key record's contents, decoded.
|
|
5
5
|
*
|
|
6
6
|
* `clientSeed` is the only always-present member: the rest are absent on
|
|
7
|
-
* records written before that member existed (a
|
|
7
|
+
* records written before that member existed (a user-key-less account, a record
|
|
8
8
|
* written before the update keys became client-held, a first client whose own
|
|
9
9
|
* did:key IS the account controller), or simply not stored by the app.
|
|
10
10
|
*/
|
|
11
11
|
export interface ClientKeyRecord {
|
|
12
12
|
clientSeed: Uint8Array;
|
|
13
|
-
|
|
13
|
+
userKey?: UserKey;
|
|
14
14
|
webvhUpdateKeys?: ClientWebvhUpdateKeys;
|
|
15
15
|
controller?: string;
|
|
16
16
|
pointerDid?: string;
|
|
@@ -22,7 +22,7 @@ export interface ClientKeyRecord {
|
|
|
22
22
|
*/
|
|
23
23
|
export interface ClientKeyRecordJson {
|
|
24
24
|
clientSeed: string;
|
|
25
|
-
|
|
25
|
+
userKey?: {
|
|
26
26
|
id: string;
|
|
27
27
|
secret: string;
|
|
28
28
|
signingSeed?: string;
|
|
@@ -38,28 +38,28 @@ export interface ClientKeyRecordJson {
|
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
40
|
* A record whose every member is present: what an ENROLLED client holds once
|
|
41
|
-
* the enrollment ceremony has landed (a key set, a delivered
|
|
41
|
+
* the enrollment ceremony has landed (a key set, a delivered user key, its own
|
|
42
42
|
* update-key seeds, and the account it belongs to).
|
|
43
43
|
*/
|
|
44
44
|
export interface EnrolledClientKeyRecord extends ClientKeyRecord {
|
|
45
|
-
|
|
45
|
+
userKey: UserKey;
|
|
46
46
|
webvhUpdateKeys: ClientWebvhUpdateKeys;
|
|
47
47
|
controller: string;
|
|
48
48
|
pointerDid: string;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* Parses and validates the optional `
|
|
52
|
-
* `undefined` (a record written for an account minted before the
|
|
53
|
-
* present-but-malformed one throws.
|
|
51
|
+
* Parses and validates the optional `userKey` member. An absent member resolves
|
|
52
|
+
* to `undefined` (a record written for an account minted before the user key);
|
|
53
|
+
* a present-but-malformed one throws.
|
|
54
54
|
*
|
|
55
|
-
* The signing seed is absent on a
|
|
55
|
+
* The signing seed is absent on a user key adopted from a roster rotation (the
|
|
56
56
|
* roster wraps the key-agreement secret alone); when present it must be
|
|
57
57
|
* well-formed.
|
|
58
58
|
*
|
|
59
|
-
* @param value {unknown} the record's `
|
|
60
|
-
* @returns {
|
|
59
|
+
* @param value {unknown} the record's `userKey` member
|
|
60
|
+
* @returns {UserKey | undefined}
|
|
61
61
|
*/
|
|
62
|
-
export declare function
|
|
62
|
+
export declare function parseClientRecordUserKey(value: unknown): UserKey | undefined;
|
|
63
63
|
/**
|
|
64
64
|
* Parses and validates the optional `webvh` member: this client's did:webvh
|
|
65
65
|
* update-key seeds. An absent member resolves to `undefined` (a record written
|
|
@@ -72,11 +72,13 @@ export declare function parseClientRecordPuk(value: unknown): Puk | undefined;
|
|
|
72
72
|
export declare function parseClientRecordWebvhKeys(value: unknown): ClientWebvhUpdateKeys | undefined;
|
|
73
73
|
/**
|
|
74
74
|
* Encodes a client-key record's contents for storage: base64url byte fields,
|
|
75
|
-
* optional members omitted rather than written as null.
|
|
75
|
+
* optional members omitted rather than written as null. Every secret is
|
|
76
|
+
* length-checked on the way out, exactly as the decoder checks it on the way
|
|
77
|
+
* back in -- an undecodable stored record is a lost account.
|
|
76
78
|
*
|
|
77
79
|
* @param options {object}
|
|
78
80
|
* @param options.clientSeed {Uint8Array} this client's 32-byte seed
|
|
79
|
-
* @param [options.
|
|
81
|
+
* @param [options.userKey] {UserKey} the cached user key
|
|
80
82
|
* @param [options.webvhUpdateKeys] {ClientWebvhUpdateKeys} this client's
|
|
81
83
|
* did:webvh update-key seeds
|
|
82
84
|
* @param [options.controller] {string} the account controller this key set
|
|
@@ -87,9 +89,9 @@ export declare function parseClientRecordWebvhKeys(value: unknown): ClientWebvhU
|
|
|
87
89
|
* to now
|
|
88
90
|
* @returns {ClientKeyRecordJson}
|
|
89
91
|
*/
|
|
90
|
-
export declare function encodeClientKeyRecord({ clientSeed,
|
|
92
|
+
export declare function encodeClientKeyRecord({ clientSeed, userKey, webvhUpdateKeys, controller, pointerDid, createdAt }: {
|
|
91
93
|
clientSeed: Uint8Array;
|
|
92
|
-
|
|
94
|
+
userKey?: UserKey;
|
|
93
95
|
webvhUpdateKeys?: ClientWebvhUpdateKeys;
|
|
94
96
|
controller?: string;
|
|
95
97
|
pointerDid?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientKeyRecord.d.ts","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clientKeyRecord.d.ts","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"AAmDA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAO3C;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,qBAAqB,CAAA;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,KAAK,CAAC,EAAE;QACN,UAAU,EAAE,MAAM,CAAA;QAClB,UAAU,EAAE,MAAM,CAAA;QAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B,CAAA;IACD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,EAAE,qBAAqB,CAAA;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CA8B5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,qBAAqB,GAAG,SAAS,CA8BnC;AAyBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,OAAO,EACP,eAAe,EACf,UAAU,EACV,UAAU,EACV,SAAoC,EACrC,EAAE;IACD,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,eAAe,CAAC,EAAE,qBAAqB,CAAA;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,mBAAmB,CAgDtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,OAAO,CAAA;CAClB,GAAG,eAAe,CAiClB;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,EAC5C,MAAM,EACP,EAAE;IACD,MAAM,EAAE,eAAe,CAAA;CACxB,GAAG,uBAAuB,CAe1B"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* The client-key record: the contents codec and validation for the local
|
|
6
6
|
* record every wallet client keeps its own key material in -- the random
|
|
7
7
|
* 32-byte client seed behind its Ed25519 signing key and X25519 twin, the
|
|
8
|
-
* cached
|
|
8
|
+
* cached user key delivered through the wrap-set roster, this
|
|
9
9
|
* client's own did:webvh update-key seeds, the account controller the record
|
|
10
10
|
* was bound for, and (when the app stores it beside the keys) the account's
|
|
11
11
|
* did:webvh pointer.
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
* wallet writes is a record the other accepts.
|
|
18
18
|
*
|
|
19
19
|
* Byte fields travel as base64url without padding; every one of them is a
|
|
20
|
-
* 32-byte secret and is length-checked on the way back in. Validation is
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
20
|
+
* 32-byte secret and is length-checked on the way back in. Validation is strict
|
|
21
|
+
* on purpose: an absent optional member is a record written before that member
|
|
22
|
+
* existed, but a present-and-malformed one throws, because both of the members
|
|
23
|
+
* that can be malformed are load-bearing -- the account's encrypted collections
|
|
24
|
+
* are keyed on the user key, and the account's identity log can only be
|
|
25
25
|
* extended with the update-key seeds, so proceeding without either would
|
|
26
26
|
* silently orphan data or strand update authority.
|
|
27
27
|
*
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
* Neither is enforceable here (the writes are the app's), and both are
|
|
30
30
|
* durability rules a crash must not be able to break:
|
|
31
31
|
*
|
|
32
|
-
* 1. **The
|
|
32
|
+
* 1. **The user key and the roster epoch pin persist atomically.** The pin is
|
|
33
|
+
* what
|
|
33
34
|
* refuses a rolled-back roster, so it must never advance without the key
|
|
34
35
|
* that authenticated the roster it advanced to -- and the key must never be
|
|
35
36
|
* adopted without the pin moving with it. One write, or none.
|
|
@@ -79,29 +80,32 @@ function decodeSecret({ value, name }) {
|
|
|
79
80
|
return bytes;
|
|
80
81
|
}
|
|
81
82
|
/**
|
|
82
|
-
* Parses and validates the optional `
|
|
83
|
-
* `undefined` (a record written for an account minted before the
|
|
84
|
-
* present-but-malformed one throws.
|
|
83
|
+
* Parses and validates the optional `userKey` member. An absent member resolves
|
|
84
|
+
* to `undefined` (a record written for an account minted before the user key);
|
|
85
|
+
* a present-but-malformed one throws.
|
|
85
86
|
*
|
|
86
|
-
* The signing seed is absent on a
|
|
87
|
+
* The signing seed is absent on a user key adopted from a roster rotation (the
|
|
87
88
|
* roster wraps the key-agreement secret alone); when present it must be
|
|
88
89
|
* well-formed.
|
|
89
90
|
*
|
|
90
|
-
* @param value {unknown} the record's `
|
|
91
|
-
* @returns {
|
|
91
|
+
* @param value {unknown} the record's `userKey` member
|
|
92
|
+
* @returns {UserKey | undefined}
|
|
92
93
|
*/
|
|
93
|
-
export function
|
|
94
|
+
export function parseClientRecordUserKey(value) {
|
|
94
95
|
if (value === undefined) {
|
|
95
96
|
return undefined;
|
|
96
97
|
}
|
|
97
98
|
if (value === null || typeof value !== 'object') {
|
|
98
|
-
throw new Error('Client-key record has a malformed
|
|
99
|
+
throw new Error('Client-key record has a malformed user key.');
|
|
99
100
|
}
|
|
100
101
|
const { id, secret, signingSeed } = value;
|
|
101
102
|
if (typeof id !== 'string' || !id) {
|
|
102
|
-
throw new Error('Client-key record
|
|
103
|
+
throw new Error('Client-key record user key is missing its key id.');
|
|
103
104
|
}
|
|
104
|
-
const secretBytes = decodeSecret({
|
|
105
|
+
const secretBytes = decodeSecret({
|
|
106
|
+
value: secret,
|
|
107
|
+
name: 'user key material'
|
|
108
|
+
});
|
|
105
109
|
if (signingSeed === undefined) {
|
|
106
110
|
return { id, secret: secretBytes };
|
|
107
111
|
}
|
|
@@ -110,7 +114,7 @@ export function parseClientRecordPuk(value) {
|
|
|
110
114
|
secret: secretBytes,
|
|
111
115
|
signingSeed: decodeSecret({
|
|
112
116
|
value: signingSeed,
|
|
113
|
-
name: '
|
|
117
|
+
name: 'user key signing seed'
|
|
114
118
|
})
|
|
115
119
|
};
|
|
116
120
|
}
|
|
@@ -150,13 +154,31 @@ export function parseClientRecordWebvhKeys(value) {
|
|
|
150
154
|
: {})
|
|
151
155
|
};
|
|
152
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Encodes one byte field, checking its length -- the encode-side twin of
|
|
159
|
+
* {@link decodeSecret}, so a record this codec writes is always a record it
|
|
160
|
+
* can read back.
|
|
161
|
+
*
|
|
162
|
+
* @param options {object}
|
|
163
|
+
* @param options.value {Uint8Array} the secret
|
|
164
|
+
* @param options.name {string} the member's name, for the error message
|
|
165
|
+
* @returns {string}
|
|
166
|
+
*/
|
|
167
|
+
function encodeSecret({ value, name }) {
|
|
168
|
+
if (value.length !== SECRET_BYTES) {
|
|
169
|
+
throw new Error(`Client-key record ${name} is not ${SECRET_BYTES} bytes.`);
|
|
170
|
+
}
|
|
171
|
+
return base64urlnopad.encode(value);
|
|
172
|
+
}
|
|
153
173
|
/**
|
|
154
174
|
* Encodes a client-key record's contents for storage: base64url byte fields,
|
|
155
|
-
* optional members omitted rather than written as null.
|
|
175
|
+
* optional members omitted rather than written as null. Every secret is
|
|
176
|
+
* length-checked on the way out, exactly as the decoder checks it on the way
|
|
177
|
+
* back in -- an undecodable stored record is a lost account.
|
|
156
178
|
*
|
|
157
179
|
* @param options {object}
|
|
158
180
|
* @param options.clientSeed {Uint8Array} this client's 32-byte seed
|
|
159
|
-
* @param [options.
|
|
181
|
+
* @param [options.userKey] {UserKey} the cached user key
|
|
160
182
|
* @param [options.webvhUpdateKeys] {ClientWebvhUpdateKeys} this client's
|
|
161
183
|
* did:webvh update-key seeds
|
|
162
184
|
* @param [options.controller] {string} the account controller this key set
|
|
@@ -167,19 +189,24 @@ export function parseClientRecordWebvhKeys(value) {
|
|
|
167
189
|
* to now
|
|
168
190
|
* @returns {ClientKeyRecordJson}
|
|
169
191
|
*/
|
|
170
|
-
export function encodeClientKeyRecord({ clientSeed,
|
|
171
|
-
if (clientSeed.length !== SECRET_BYTES) {
|
|
172
|
-
throw new Error(`Client-key record client seed is not ${SECRET_BYTES} bytes.`);
|
|
173
|
-
}
|
|
192
|
+
export function encodeClientKeyRecord({ clientSeed, userKey, webvhUpdateKeys, controller, pointerDid, createdAt = new Date().toISOString() }) {
|
|
174
193
|
return {
|
|
175
|
-
clientSeed:
|
|
176
|
-
...(
|
|
194
|
+
clientSeed: encodeSecret({ value: clientSeed, name: 'client seed' }),
|
|
195
|
+
...(userKey
|
|
177
196
|
? {
|
|
178
|
-
|
|
179
|
-
id:
|
|
180
|
-
secret:
|
|
181
|
-
|
|
182
|
-
|
|
197
|
+
userKey: {
|
|
198
|
+
id: userKey.id,
|
|
199
|
+
secret: encodeSecret({
|
|
200
|
+
value: userKey.secret,
|
|
201
|
+
name: 'user key material'
|
|
202
|
+
}),
|
|
203
|
+
...(userKey.signingSeed
|
|
204
|
+
? {
|
|
205
|
+
signingSeed: encodeSecret({
|
|
206
|
+
value: userKey.signingSeed,
|
|
207
|
+
name: 'user key signing seed'
|
|
208
|
+
})
|
|
209
|
+
}
|
|
183
210
|
: {})
|
|
184
211
|
}
|
|
185
212
|
}
|
|
@@ -187,11 +214,20 @@ export function encodeClientKeyRecord({ clientSeed, puk, webvhUpdateKeys, contro
|
|
|
187
214
|
...(webvhUpdateKeys
|
|
188
215
|
? {
|
|
189
216
|
webvh: {
|
|
190
|
-
updateSeed:
|
|
191
|
-
|
|
217
|
+
updateSeed: encodeSecret({
|
|
218
|
+
value: webvhUpdateKeys.updateSeed,
|
|
219
|
+
name: 'did:webvh update seed'
|
|
220
|
+
}),
|
|
221
|
+
stagedSeed: encodeSecret({
|
|
222
|
+
value: webvhUpdateKeys.stagedSeed,
|
|
223
|
+
name: 'did:webvh staged seed'
|
|
224
|
+
}),
|
|
192
225
|
...(webvhUpdateKeys.pendingStagedSeed
|
|
193
226
|
? {
|
|
194
|
-
pendingStagedSeed:
|
|
227
|
+
pendingStagedSeed: encodeSecret({
|
|
228
|
+
value: webvhUpdateKeys.pendingStagedSeed,
|
|
229
|
+
name: 'did:webvh pending staged seed'
|
|
230
|
+
})
|
|
195
231
|
}
|
|
196
232
|
: {})
|
|
197
233
|
}
|
|
@@ -216,7 +252,7 @@ export function decodeClientKeyRecord({ contents }) {
|
|
|
216
252
|
if (contents === null || typeof contents !== 'object') {
|
|
217
253
|
throw new Error('Malformed client-key record.');
|
|
218
254
|
}
|
|
219
|
-
const { clientSeed,
|
|
255
|
+
const { clientSeed, userKey, webvh, controller, pointerDid } = contents;
|
|
220
256
|
const seed = decodeSecret({ value: clientSeed, name: 'client seed' });
|
|
221
257
|
if (controller !== undefined &&
|
|
222
258
|
(typeof controller !== 'string' || !controller)) {
|
|
@@ -226,11 +262,11 @@ export function decodeClientKeyRecord({ contents }) {
|
|
|
226
262
|
(typeof pointerDid !== 'string' || !pointerDid)) {
|
|
227
263
|
throw new Error('Client-key record has a malformed account pointer DID.');
|
|
228
264
|
}
|
|
229
|
-
const
|
|
265
|
+
const parsedUserKey = parseClientRecordUserKey(userKey);
|
|
230
266
|
const webvhUpdateKeys = parseClientRecordWebvhKeys(webvh);
|
|
231
267
|
return {
|
|
232
268
|
clientSeed: seed,
|
|
233
|
-
...(
|
|
269
|
+
...(parsedUserKey ? { userKey: parsedUserKey } : {}),
|
|
234
270
|
...(webvhUpdateKeys ? { webvhUpdateKeys } : {}),
|
|
235
271
|
...(controller ? { controller } : {}),
|
|
236
272
|
...(pointerDid ? { pointerDid } : {})
|
|
@@ -247,9 +283,9 @@ export function decodeClientKeyRecord({ contents }) {
|
|
|
247
283
|
* @returns {EnrolledClientKeyRecord}
|
|
248
284
|
*/
|
|
249
285
|
export function assertEnrolledClientKeyRecord({ record }) {
|
|
250
|
-
const {
|
|
251
|
-
if (!
|
|
252
|
-
throw new Error('Client-key record carries no
|
|
286
|
+
const { userKey, webvhUpdateKeys, controller, pointerDid } = record;
|
|
287
|
+
if (!userKey) {
|
|
288
|
+
throw new Error('Client-key record carries no user key.');
|
|
253
289
|
}
|
|
254
290
|
if (!webvhUpdateKeys) {
|
|
255
291
|
throw new Error('Client-key record carries no did:webvh update keys.');
|
|
@@ -260,6 +296,6 @@ export function assertEnrolledClientKeyRecord({ record }) {
|
|
|
260
296
|
if (!pointerDid) {
|
|
261
297
|
throw new Error('Client-key record carries no account pointer DID.');
|
|
262
298
|
}
|
|
263
|
-
return { ...record,
|
|
299
|
+
return { ...record, userKey, webvhUpdateKeys, controller, pointerDid };
|
|
264
300
|
}
|
|
265
301
|
//# sourceMappingURL=clientKeyRecord.js.map
|