@interop/wallet-core 0.17.1 → 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 +15 -15
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +19 -19
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +26 -25
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +29 -29
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts +16 -16
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +19 -19
- 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 +16 -16
- package/dist/keys/clientKeyRecord.d.ts.map +1 -1
- package/dist/keys/clientKeyRecord.js +39 -35
- 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} +67 -64
- package/dist/keys/userKeyCascade.js.map +1 -0
- package/dist/keys/{pukRoster.d.ts → userKeyRoster.d.ts} +73 -74
- package/dist/keys/userKeyRoster.d.ts.map +1 -0
- package/dist/keys/{pukRoster.js → userKeyRoster.js} +86 -83
- 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/space/activity.d.ts +1 -1
- package/dist/space/activity.js +1 -1
- package/dist/space/collections.d.ts +17 -17
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +16 -16
- 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/webvh/didWebvh.d.ts +1 -1
- package/dist/webvh/didWebvh.js +6 -6
- package/package.json +1 -1
- 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
|
@@ -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
|
}
|
|
@@ -174,7 +178,7 @@ function encodeSecret({ value, name }) {
|
|
|
174
178
|
*
|
|
175
179
|
* @param options {object}
|
|
176
180
|
* @param options.clientSeed {Uint8Array} this client's 32-byte seed
|
|
177
|
-
* @param [options.
|
|
181
|
+
* @param [options.userKey] {UserKey} the cached user key
|
|
178
182
|
* @param [options.webvhUpdateKeys] {ClientWebvhUpdateKeys} this client's
|
|
179
183
|
* did:webvh update-key seeds
|
|
180
184
|
* @param [options.controller] {string} the account controller this key set
|
|
@@ -185,22 +189,22 @@ function encodeSecret({ value, name }) {
|
|
|
185
189
|
* to now
|
|
186
190
|
* @returns {ClientKeyRecordJson}
|
|
187
191
|
*/
|
|
188
|
-
export function encodeClientKeyRecord({ clientSeed,
|
|
192
|
+
export function encodeClientKeyRecord({ clientSeed, userKey, webvhUpdateKeys, controller, pointerDid, createdAt = new Date().toISOString() }) {
|
|
189
193
|
return {
|
|
190
194
|
clientSeed: encodeSecret({ value: clientSeed, name: 'client seed' }),
|
|
191
|
-
...(
|
|
195
|
+
...(userKey
|
|
192
196
|
? {
|
|
193
|
-
|
|
194
|
-
id:
|
|
197
|
+
userKey: {
|
|
198
|
+
id: userKey.id,
|
|
195
199
|
secret: encodeSecret({
|
|
196
|
-
value:
|
|
197
|
-
name: '
|
|
200
|
+
value: userKey.secret,
|
|
201
|
+
name: 'user key material'
|
|
198
202
|
}),
|
|
199
|
-
...(
|
|
203
|
+
...(userKey.signingSeed
|
|
200
204
|
? {
|
|
201
205
|
signingSeed: encodeSecret({
|
|
202
|
-
value:
|
|
203
|
-
name: '
|
|
206
|
+
value: userKey.signingSeed,
|
|
207
|
+
name: 'user key signing seed'
|
|
204
208
|
})
|
|
205
209
|
}
|
|
206
210
|
: {})
|
|
@@ -248,7 +252,7 @@ export function decodeClientKeyRecord({ contents }) {
|
|
|
248
252
|
if (contents === null || typeof contents !== 'object') {
|
|
249
253
|
throw new Error('Malformed client-key record.');
|
|
250
254
|
}
|
|
251
|
-
const { clientSeed,
|
|
255
|
+
const { clientSeed, userKey, webvh, controller, pointerDid } = contents;
|
|
252
256
|
const seed = decodeSecret({ value: clientSeed, name: 'client seed' });
|
|
253
257
|
if (controller !== undefined &&
|
|
254
258
|
(typeof controller !== 'string' || !controller)) {
|
|
@@ -258,11 +262,11 @@ export function decodeClientKeyRecord({ contents }) {
|
|
|
258
262
|
(typeof pointerDid !== 'string' || !pointerDid)) {
|
|
259
263
|
throw new Error('Client-key record has a malformed account pointer DID.');
|
|
260
264
|
}
|
|
261
|
-
const
|
|
265
|
+
const parsedUserKey = parseClientRecordUserKey(userKey);
|
|
262
266
|
const webvhUpdateKeys = parseClientRecordWebvhKeys(webvh);
|
|
263
267
|
return {
|
|
264
268
|
clientSeed: seed,
|
|
265
|
-
...(
|
|
269
|
+
...(parsedUserKey ? { userKey: parsedUserKey } : {}),
|
|
266
270
|
...(webvhUpdateKeys ? { webvhUpdateKeys } : {}),
|
|
267
271
|
...(controller ? { controller } : {}),
|
|
268
272
|
...(pointerDid ? { pointerDid } : {})
|
|
@@ -279,9 +283,9 @@ export function decodeClientKeyRecord({ contents }) {
|
|
|
279
283
|
* @returns {EnrolledClientKeyRecord}
|
|
280
284
|
*/
|
|
281
285
|
export function assertEnrolledClientKeyRecord({ record }) {
|
|
282
|
-
const {
|
|
283
|
-
if (!
|
|
284
|
-
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.');
|
|
285
289
|
}
|
|
286
290
|
if (!webvhUpdateKeys) {
|
|
287
291
|
throw new Error('Client-key record carries no did:webvh update keys.');
|
|
@@ -292,6 +296,6 @@ export function assertEnrolledClientKeyRecord({ record }) {
|
|
|
292
296
|
if (!pointerDid) {
|
|
293
297
|
throw new Error('Client-key record carries no account pointer DID.');
|
|
294
298
|
}
|
|
295
|
-
return { ...record,
|
|
299
|
+
return { ...record, userKey, webvhUpdateKeys, controller, pointerDid };
|
|
296
300
|
}
|
|
297
301
|
//# sourceMappingURL=clientKeyRecord.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientKeyRecord.js","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"clientKeyRecord.js","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"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"}
|
package/dist/keys/index.d.ts
CHANGED
|
@@ -2,48 +2,50 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The `@interop/wallet-core/keys` subpath: the
|
|
5
|
+
* The `@interop/wallet-core/keys` subpath: the user key and its
|
|
6
6
|
* wrap-set roster -- recipient zero of every encrypted collection, and the one
|
|
7
7
|
* channel that delivers it to each enrolled wallet client.
|
|
8
8
|
*
|
|
9
|
-
* - `
|
|
9
|
+
* - `mintUserKey` / `userKeyVaultKeys` -- minting the account's user key and
|
|
10
|
+
* rebuilding the
|
|
10
11
|
* vault key-agreement key + resolver from stored material.
|
|
11
12
|
* - `encodeClientKeyRecord` / `decodeClientKeyRecord` -- the contents codec and
|
|
12
13
|
* strict validation of the local client-key record each client keeps its own
|
|
13
14
|
* key material in (storage and wrapping stay app-side).
|
|
14
|
-
* - `
|
|
15
|
-
* `
|
|
15
|
+
* - `ensureUserKeyRoster` / `addUserKeyRosterRecipient` / `readUserKeyRoster` /
|
|
16
|
+
* `userKeyRosterRecipientResolver` -- the `key-map/user-key.json` roster over the
|
|
16
17
|
* was-client descriptor-store seam, with the three client-side guards a
|
|
17
18
|
* resource-hosted descriptor needs (`epochsMac`, the latest-seen epoch pin,
|
|
18
19
|
* and a recipient resolver backed by the locally verified did:webvh
|
|
19
20
|
* document).
|
|
20
|
-
* - `
|
|
21
|
+
* - `userKeyRosterDescriptorStore` -- that descriptor store, built from a bare
|
|
21
22
|
* signing client for the login-time direct read.
|
|
22
23
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
23
24
|
* the enrollment wrap, the roster read, and the rotation that retires it.
|
|
24
|
-
* - `
|
|
25
|
+
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
25
26
|
* cascade torn between the document edit and the roster rotation: a roster
|
|
26
27
|
* recipient the document no longer keys is rotated away from.
|
|
27
28
|
* - `readClientLabels` / `setClientLabel` / `removeClientLabel` /
|
|
28
29
|
* `wasClientLabelsStore` -- the enrolled-client display labels
|
|
29
30
|
* (`key-map/client-labels.json`), the record a "your wallets" surface names
|
|
30
31
|
* clients from, and the WAS-backed store they run through.
|
|
31
|
-
* - `
|
|
32
|
-
*
|
|
32
|
+
* - `rotateUserKeyRoster` / `unwrapUserKeyGenerations` /
|
|
33
|
+
* `rotateCollectionEpochsToUserKey`
|
|
34
|
+
* / `cascadeCollectionsToUserKey` / `userKeyAsRecipient` -- the user key rotation
|
|
33
35
|
* cascade: the roster rotation off a revoked recipient, the per-collection
|
|
34
36
|
* re-epoch that brings an encrypted collection onto the roster's current
|
|
35
|
-
*
|
|
37
|
+
* user key, and the parallel best-effort fan-out over the collections the wallet
|
|
36
38
|
* names (also the completion sweep's driver).
|
|
37
39
|
*/
|
|
38
|
-
export {
|
|
39
|
-
export type {
|
|
40
|
-
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord,
|
|
40
|
+
export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
41
|
+
export type { UserKey } from './userKey.js';
|
|
42
|
+
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
41
43
|
export type { ClientKeyRecord, ClientKeyRecordJson, EnrolledClientKeyRecord } from './clientKeyRecord.js';
|
|
42
|
-
export {
|
|
43
|
-
export {
|
|
44
|
-
export type {
|
|
45
|
-
export type {
|
|
46
|
-
export {
|
|
44
|
+
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterEpochsSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster, verifyUserKeyRosterEpochsSig } from './userKeyRoster.js';
|
|
45
|
+
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
46
|
+
export type { CollectionUserKeyRotationOutcome, UserKeyCascadeResult } from './userKeyCascade.js';
|
|
47
|
+
export type { UserKeyRosterReadResult, RosterRecipientDocument } from './userKeyRoster.js';
|
|
48
|
+
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
47
49
|
export { readClientLabels, removeClientLabel, setClientLabel } from './clientLabels.js';
|
|
48
50
|
export type { ClientLabelsRecord, ClientLabelsStore } from './clientLabels.js';
|
|
49
51
|
export { wasClientLabelsStore } from './wasLabelsStore.js';
|
package/dist/keys/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC5D,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC7B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,gCAAgC,EAChC,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/keys/index.js
CHANGED
|
@@ -2,44 +2,46 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The `@interop/wallet-core/keys` subpath: the
|
|
5
|
+
* The `@interop/wallet-core/keys` subpath: the user key and its
|
|
6
6
|
* wrap-set roster -- recipient zero of every encrypted collection, and the one
|
|
7
7
|
* channel that delivers it to each enrolled wallet client.
|
|
8
8
|
*
|
|
9
|
-
* - `
|
|
9
|
+
* - `mintUserKey` / `userKeyVaultKeys` -- minting the account's user key and
|
|
10
|
+
* rebuilding the
|
|
10
11
|
* vault key-agreement key + resolver from stored material.
|
|
11
12
|
* - `encodeClientKeyRecord` / `decodeClientKeyRecord` -- the contents codec and
|
|
12
13
|
* strict validation of the local client-key record each client keeps its own
|
|
13
14
|
* key material in (storage and wrapping stay app-side).
|
|
14
|
-
* - `
|
|
15
|
-
* `
|
|
15
|
+
* - `ensureUserKeyRoster` / `addUserKeyRosterRecipient` / `readUserKeyRoster` /
|
|
16
|
+
* `userKeyRosterRecipientResolver` -- the `key-map/user-key.json` roster over the
|
|
16
17
|
* was-client descriptor-store seam, with the three client-side guards a
|
|
17
18
|
* resource-hosted descriptor needs (`epochsMac`, the latest-seen epoch pin,
|
|
18
19
|
* and a recipient resolver backed by the locally verified did:webvh
|
|
19
20
|
* document).
|
|
20
|
-
* - `
|
|
21
|
+
* - `userKeyRosterDescriptorStore` -- that descriptor store, built from a bare
|
|
21
22
|
* signing client for the login-time direct read.
|
|
22
23
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
23
24
|
* the enrollment wrap, the roster read, and the rotation that retires it.
|
|
24
|
-
* - `
|
|
25
|
+
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
25
26
|
* cascade torn between the document edit and the roster rotation: a roster
|
|
26
27
|
* recipient the document no longer keys is rotated away from.
|
|
27
28
|
* - `readClientLabels` / `setClientLabel` / `removeClientLabel` /
|
|
28
29
|
* `wasClientLabelsStore` -- the enrolled-client display labels
|
|
29
30
|
* (`key-map/client-labels.json`), the record a "your wallets" surface names
|
|
30
31
|
* clients from, and the WAS-backed store they run through.
|
|
31
|
-
* - `
|
|
32
|
-
*
|
|
32
|
+
* - `rotateUserKeyRoster` / `unwrapUserKeyGenerations` /
|
|
33
|
+
* `rotateCollectionEpochsToUserKey`
|
|
34
|
+
* / `cascadeCollectionsToUserKey` / `userKeyAsRecipient` -- the user key rotation
|
|
33
35
|
* cascade: the roster rotation off a revoked recipient, the per-collection
|
|
34
36
|
* re-epoch that brings an encrypted collection onto the roster's current
|
|
35
|
-
*
|
|
37
|
+
* user key, and the parallel best-effort fan-out over the collections the wallet
|
|
36
38
|
* names (also the completion sweep's driver).
|
|
37
39
|
*/
|
|
38
|
-
export {
|
|
39
|
-
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord,
|
|
40
|
-
export {
|
|
41
|
-
export {
|
|
42
|
-
export {
|
|
40
|
+
export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
41
|
+
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
42
|
+
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterEpochsSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster, verifyUserKeyRosterEpochsSig } from './userKeyRoster.js';
|
|
43
|
+
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
44
|
+
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
43
45
|
export { readClientLabels, removeClientLabel, setClientLabel } from './clientLabels.js';
|
|
44
46
|
export { wasClientLabelsStore } from './wasLabelsStore.js';
|
|
45
47
|
//# sourceMappingURL=index.js.map
|
package/dist/keys/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG5D,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC7B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAU5B,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ZcapClient } from '@interop/ezcap';
|
|
2
2
|
import { type EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
3
3
|
/**
|
|
4
|
-
* Builds the compare-and-swap descriptor store over `key-map/
|
|
5
|
-
* data Space.
|
|
4
|
+
* Builds the compare-and-swap descriptor store over `key-map/user-key.json` in
|
|
5
|
+
* a data Space.
|
|
6
6
|
*
|
|
7
7
|
* @param options {object}
|
|
8
8
|
* @param options.storageServerUrl {string}
|
|
@@ -10,7 +10,7 @@ import { type EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
|
10
10
|
* @param options.spaceId {string} the data Space id
|
|
11
11
|
* @returns {EncryptionDescriptorStore}
|
|
12
12
|
*/
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }: {
|
|
14
14
|
storageServerUrl: string;
|
|
15
15
|
zcapClient: ZcapClient;
|
|
16
16
|
spaceId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAMhC;;;;;;;;;GASG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAMhC;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EACR,EAAE;IACD,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,yBAAyB,CAQ5B"}
|
package/dist/keys/rosterStore.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The descriptor store over a Space's
|
|
6
|
-
* Standalone rather than a method on a wallet's
|
|
7
|
-
* the login-time direct read checks the roster
|
|
8
|
-
* cipher) is built: it takes the bare signing
|
|
9
|
-
* instance.
|
|
5
|
+
* The descriptor store over a Space's user key wrap-set roster
|
|
6
|
+
* (`key-map/user-key.json`). Standalone rather than a method on a wallet's
|
|
7
|
+
* remote-store class, because the login-time direct read checks the roster
|
|
8
|
+
* BEFORE any storage client (or cipher) is built: it takes the bare signing
|
|
9
|
+
* client instead of a store instance.
|
|
10
10
|
*
|
|
11
11
|
* The `plaintext` collection override is load-bearing. Without it the client
|
|
12
12
|
* decides plaintext vs encrypted by describing the collection first, and a 404
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { WasClient } from '@interop/was-client';
|
|
17
17
|
import { resourceDescriptorStore } from '@interop/was-client/edv';
|
|
18
|
-
import { KEY_MAP_COLLECTION,
|
|
18
|
+
import { KEY_MAP_COLLECTION, USER_KEY_ROSTER_RESOURCE } from '../space/collections.js';
|
|
19
19
|
/**
|
|
20
|
-
* Builds the compare-and-swap descriptor store over `key-map/
|
|
21
|
-
* data Space.
|
|
20
|
+
* Builds the compare-and-swap descriptor store over `key-map/user-key.json` in
|
|
21
|
+
* a data Space.
|
|
22
22
|
*
|
|
23
23
|
* @param options {object}
|
|
24
24
|
* @param options.storageServerUrl {string}
|
|
@@ -26,13 +26,13 @@ import { KEY_MAP_COLLECTION, PUK_ROSTER_RESOURCE } from '../space/collections.js
|
|
|
26
26
|
* @param options.spaceId {string} the data Space id
|
|
27
27
|
* @returns {EncryptionDescriptorStore}
|
|
28
28
|
*/
|
|
29
|
-
export function
|
|
29
|
+
export function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }) {
|
|
30
30
|
const was = new WasClient({ serverUrl: storageServerUrl, zcapClient });
|
|
31
|
+
const collection = was
|
|
32
|
+
.space(spaceId)
|
|
33
|
+
.collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' });
|
|
31
34
|
return resourceDescriptorStore({
|
|
32
|
-
resource:
|
|
33
|
-
.space(spaceId)
|
|
34
|
-
.collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' })
|
|
35
|
-
.resource(PUK_ROSTER_RESOURCE)
|
|
35
|
+
resource: collection.resource(USER_KEY_ROSTER_RESOURCE)
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
//# sourceMappingURL=rosterStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EACL,uBAAuB,EAExB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EACL,uBAAuB,EAExB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,yBAAyB,CAAA;AAEhC;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EAKR;IACC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IACtE,MAAM,UAAU,GAAG,GAAG;SACnB,KAAK,CAAC,OAAO,CAAC;SACd,UAAU,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;IACjE,OAAO,uBAAuB,CAAC;QAC7B,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,wBAAwB,CAAC;KACxD,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
|
|
2
|
+
/**
|
|
3
|
+
* The user key material: the X25519 key-agreement half as minted by the epoch
|
|
4
|
+
* construction (`id` is the key's own did:key; `secret` its raw 32-byte private
|
|
5
|
+
* key), plus the 32-byte seed of the user key's Ed25519 signing pair. Random
|
|
6
|
+
* per account; held in memory for the life of a session and persisted only
|
|
7
|
+
* inside a wrapped client-key record. The signing seed is absent on a user key
|
|
8
|
+
* adopted from a roster rotation -- the roster wraps the key-agreement secret
|
|
9
|
+
* alone, and the signing half has no consumer yet.
|
|
10
|
+
*/
|
|
11
|
+
export interface UserKey {
|
|
12
|
+
id: string;
|
|
13
|
+
secret: Uint8Array;
|
|
14
|
+
signingSeed?: Uint8Array;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Mints a fresh user key: the X25519 key-agreement pair via the was-client
|
|
18
|
+
* epoch construction (its did:key is the key id, its raw secret is what wraps),
|
|
19
|
+
* plus a random 32-byte Ed25519 signing seed -- a minted user key is always a
|
|
20
|
+
* complete identity (only a rotation-adopted one lacks the signing half).
|
|
21
|
+
*
|
|
22
|
+
* @returns {Promise<Required<UserKey>>}
|
|
23
|
+
*/
|
|
24
|
+
export declare function mintUserKey(): Promise<Required<UserKey>>;
|
|
25
|
+
/**
|
|
26
|
+
* Reconstructs the user key's key-agreement key and its single-key resolver
|
|
27
|
+
* from the stored material -- the vault-key pair a session supplies to the
|
|
28
|
+
* storage layer, making the user key recipient zero of every encrypted
|
|
29
|
+
* collection. The key id is the self-describing `<did:key>#<fingerprint>` form,
|
|
30
|
+
* so grantee-side did:key recipient resolution routes it like any other roster
|
|
31
|
+
* entry.
|
|
32
|
+
*
|
|
33
|
+
* @param options {object}
|
|
34
|
+
* @param options.userKey {UserKey}
|
|
35
|
+
* @returns {{ keyAgreementKey: IKeyAgreementKey, keyResolver: IKeyResolver }}
|
|
36
|
+
*/
|
|
37
|
+
export declare function userKeyVaultKeys({ userKey }: {
|
|
38
|
+
userKey: UserKey;
|
|
39
|
+
}): {
|
|
40
|
+
keyAgreementKey: IKeyAgreementKey;
|
|
41
|
+
keyResolver: IKeyResolver;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=userKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userKey.d.ts","sourceRoot":"","sources":["../../src/keys/userKey.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AAIrC;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,UAAU,CAAA;IAClB,WAAW,CAAC,EAAE,UAAU,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAK9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IACnE,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B,CAQA"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The
|
|
5
|
+
* The user key: the user's single roster identity for encrypted
|
|
6
6
|
* collections, standing in as "recipient zero" of every key-epoch roster. It is
|
|
7
7
|
* minted at wallet provisioning -- random, client-side, never server-held, and
|
|
8
8
|
* never derivable from any passphrase or seed -- and delivered to each enrolled
|
|
@@ -12,45 +12,47 @@
|
|
|
12
12
|
* The key-agreement half is exactly what `@interop/was-client`'s epoch
|
|
13
13
|
* construction mints: a fresh X25519 pair whose did:key is the key's id and
|
|
14
14
|
* whose raw 32-byte secret is what gets wrapped to recipients -- so the roster
|
|
15
|
-
* machinery consumes the
|
|
16
|
-
* independent 32-byte seed, minted now so the
|
|
17
|
-
* no consumer yet (the pair derives from the seed on demand once
|
|
15
|
+
* machinery consumes the user key unchanged. The Ed25519 signing half is a
|
|
16
|
+
* second independent 32-byte seed, minted now so the user key is a complete
|
|
17
|
+
* identity, with no consumer yet (the pair derives from the seed on demand once
|
|
18
|
+
* one lands).
|
|
18
19
|
*/
|
|
19
20
|
import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key';
|
|
20
21
|
import { epochKeyIdFor, mintEpoch } from '@interop/was-client/edv';
|
|
21
22
|
import { singleKeyResolver } from '../identity/keyResolver.js';
|
|
22
23
|
/**
|
|
23
|
-
* Mints a fresh
|
|
24
|
-
* construction (its did:key is the key id, its raw secret is what wraps),
|
|
25
|
-
* a random 32-byte Ed25519 signing seed -- a minted
|
|
26
|
-
* identity (only a rotation-adopted one lacks the signing half).
|
|
24
|
+
* Mints a fresh user key: the X25519 key-agreement pair via the was-client
|
|
25
|
+
* epoch construction (its did:key is the key id, its raw secret is what wraps),
|
|
26
|
+
* plus a random 32-byte Ed25519 signing seed -- a minted user key is always a
|
|
27
|
+
* complete identity (only a rotation-adopted one lacks the signing half).
|
|
27
28
|
*
|
|
28
|
-
* @returns {Promise<Required<
|
|
29
|
+
* @returns {Promise<Required<UserKey>>}
|
|
29
30
|
*/
|
|
30
|
-
export async function
|
|
31
|
+
export async function mintUserKey() {
|
|
31
32
|
const { epochId, secret } = await mintEpoch();
|
|
32
33
|
const signingSeed = new Uint8Array(32);
|
|
33
34
|
crypto.getRandomValues(signingSeed);
|
|
34
35
|
return { id: epochId, secret, signingSeed };
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
37
|
-
* Reconstructs the
|
|
38
|
-
* the stored material -- the vault-key pair a session supplies to the
|
|
39
|
-
* layer, making the
|
|
40
|
-
* id is the self-describing `<did:key>#<fingerprint>` form,
|
|
41
|
-
* did:key recipient resolution routes it like any other roster
|
|
38
|
+
* Reconstructs the user key's key-agreement key and its single-key resolver
|
|
39
|
+
* from the stored material -- the vault-key pair a session supplies to the
|
|
40
|
+
* storage layer, making the user key recipient zero of every encrypted
|
|
41
|
+
* collection. The key id is the self-describing `<did:key>#<fingerprint>` form,
|
|
42
|
+
* so grantee-side did:key recipient resolution routes it like any other roster
|
|
43
|
+
* entry.
|
|
42
44
|
*
|
|
43
45
|
* @param options {object}
|
|
44
|
-
* @param options.
|
|
46
|
+
* @param options.userKey {UserKey}
|
|
45
47
|
* @returns {{ keyAgreementKey: IKeyAgreementKey, keyResolver: IKeyResolver }}
|
|
46
48
|
*/
|
|
47
|
-
export function
|
|
49
|
+
export function userKeyVaultKeys({ userKey }) {
|
|
48
50
|
const keyAgreementKey = X25519KeyAgreementKey2020.fromRawSecret({
|
|
49
|
-
secret:
|
|
50
|
-
controller:
|
|
51
|
-
id: epochKeyIdFor(
|
|
51
|
+
secret: userKey.secret,
|
|
52
|
+
controller: userKey.id,
|
|
53
|
+
id: epochKeyIdFor(userKey.id)
|
|
52
54
|
});
|
|
53
55
|
const keyResolver = singleKeyResolver({ keyAgreementKey });
|
|
54
56
|
return { keyAgreementKey, keyResolver };
|
|
55
57
|
}
|
|
56
|
-
//# sourceMappingURL=
|
|
58
|
+
//# sourceMappingURL=userKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userKey.js","sourceRoot":"","sources":["../../src/keys/userKey.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAK7E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAiB9D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,EAAE,CAAA;IAC7C,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAA;IACnC,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;AAC7C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAAwB;IAIhE,MAAM,eAAe,GAAG,yBAAyB,CAAC,aAAa,CAAC;QAC9D,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU,EAAE,OAAO,CAAC,EAAE;QACtB,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;KAC9B,CAAqB,CAAA;IACtB,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,eAAe,EAAE,CAAC,CAAA;IAC1D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,CAAA;AACzC,CAAC"}
|