@interop/did-cli 0.8.0 → 0.10.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/CHANGELOG.md +158 -0
- package/README.md +386 -4
- package/dist/commands/did.d.ts +9 -0
- package/dist/commands/did.d.ts.map +1 -1
- package/dist/commands/did.js +1041 -20
- package/dist/commands/did.js.map +1 -1
- package/dist/commands/edv.d.ts +63 -0
- package/dist/commands/edv.d.ts.map +1 -0
- package/dist/commands/edv.js +627 -0
- package/dist/commands/edv.js.map +1 -0
- package/dist/commands/key.d.ts.map +1 -1
- package/dist/commands/key.js +44 -8
- package/dist/commands/key.js.map +1 -1
- package/dist/commands/was/space.d.ts +17 -0
- package/dist/commands/was/space.d.ts.map +1 -1
- package/dist/commands/was/space.js +37 -2
- package/dist/commands/was/space.js.map +1 -1
- package/dist/commands/was.d.ts +1 -1
- package/dist/commands/was.d.ts.map +1 -1
- package/dist/commands/was.js +11 -2
- package/dist/commands/was.js.map +1 -1
- package/dist/edv/core.d.ts +60 -0
- package/dist/edv/core.d.ts.map +1 -0
- package/dist/edv/core.js +75 -0
- package/dist/edv/core.js.map +1 -0
- package/dist/edv/document.d.ts +25 -0
- package/dist/edv/document.d.ts.map +1 -0
- package/dist/edv/document.js +19 -0
- package/dist/edv/document.js.map +1 -0
- package/dist/edv/hmac.d.ts +26 -0
- package/dist/edv/hmac.d.ts.map +1 -0
- package/dist/edv/hmac.js +67 -0
- package/dist/edv/hmac.js.map +1 -0
- package/dist/edv/recipients.d.ts +65 -0
- package/dist/edv/recipients.d.ts.map +1 -0
- package/dist/edv/recipients.js +253 -0
- package/dist/edv/recipients.js.map +1 -0
- package/dist/edv/stream.d.ts +69 -0
- package/dist/edv/stream.d.ts.map +1 -0
- package/dist/edv/stream.js +169 -0
- package/dist/edv/stream.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/keys/webvh-driver.d.ts +24 -0
- package/dist/keys/webvh-driver.d.ts.map +1 -0
- package/dist/keys/webvh-driver.js +73 -0
- package/dist/keys/webvh-driver.js.map +1 -0
- package/dist/keys/webvh-signer.d.ts +29 -0
- package/dist/keys/webvh-signer.d.ts.map +1 -0
- package/dist/keys/webvh-signer.js +44 -0
- package/dist/keys/webvh-signer.js.map +1 -0
- package/dist/keys/webvh-update.d.ts +33 -0
- package/dist/keys/webvh-update.d.ts.map +1 -0
- package/dist/keys/webvh-update.js +62 -0
- package/dist/keys/webvh-update.js.map +1 -0
- package/dist/meta.d.ts +1 -0
- package/dist/meta.d.ts.map +1 -1
- package/dist/meta.js +1 -1
- package/dist/meta.js.map +1 -1
- package/dist/storage.d.ts +80 -4
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +75 -6
- package/dist/storage.js.map +1 -1
- package/dist/was/io.d.ts +14 -0
- package/dist/was/io.d.ts.map +1 -1
- package/dist/was/io.js +20 -7
- package/dist/was/io.js.map +1 -1
- package/dist/was/registry.d.ts +2 -1
- package/dist/was/registry.d.ts.map +1 -1
- package/dist/was/registry.js +16 -5
- package/dist/was/registry.js.map +1 -1
- package/package.json +9 -6
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared EDV Document types and the envelope detector for the `edv` command.
|
|
3
|
+
*
|
|
4
|
+
* The `{ id, sequence, indexed, jwe }` envelope -- the document the EDV / WAS
|
|
5
|
+
* data model stores -- is assembled and unwrapped by `@interop/edv-client`'s
|
|
6
|
+
* `EdvClientCore` (see `./core.ts`); Phases 1-2's hand-rolled assembly was
|
|
7
|
+
* retired in Phase 3 in favor of that reference implementation. This module
|
|
8
|
+
* keeps only what the command layer needs alongside it: the decrypted payload
|
|
9
|
+
* shape and the `isEncryptedDocument` discriminator that tells an EDV Document
|
|
10
|
+
* envelope apart from a bare Layer 1 JWE on read.
|
|
11
|
+
*/
|
|
12
|
+
import type { IEDVDocument, IEncryptedDocument } from '@interop/data-integrity-core';
|
|
13
|
+
/** Filename convention for a serialized EDV Document. */
|
|
14
|
+
export declare const EDV_DOCUMENT_FILE_SUFFIX = ".edvdoc.json";
|
|
15
|
+
/** The decrypted payload an EDV Document's JWE protects. */
|
|
16
|
+
export type DocumentPayload = Pick<IEDVDocument, 'content' | 'meta' | 'stream'>;
|
|
17
|
+
/**
|
|
18
|
+
* True when a parsed value is an encrypted EDV Document envelope (it carries a
|
|
19
|
+
* string `id` and an object `jwe`), as opposed to a bare Layer 1 JWE.
|
|
20
|
+
*
|
|
21
|
+
* @param value {unknown}
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
export declare function isEncryptedDocument(value: unknown): value is IEncryptedDocument;
|
|
25
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/edv/document.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EACnB,MAAM,8BAA8B,CAAA;AAErC,yDAAyD;AACzD,eAAO,MAAM,wBAAwB,iBAAiB,CAAA;AAEtD,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAA;AAE/E;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,kBAAkB,CAU7B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Filename convention for a serialized EDV Document. */
|
|
2
|
+
export const EDV_DOCUMENT_FILE_SUFFIX = '.edvdoc.json';
|
|
3
|
+
/**
|
|
4
|
+
* True when a parsed value is an encrypted EDV Document envelope (it carries a
|
|
5
|
+
* string `id` and an object `jwe`), as opposed to a bare Layer 1 JWE.
|
|
6
|
+
*
|
|
7
|
+
* @param value {unknown}
|
|
8
|
+
* @returns {boolean}
|
|
9
|
+
*/
|
|
10
|
+
export function isEncryptedDocument(value) {
|
|
11
|
+
if (value === null || typeof value !== 'object') {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
const candidate = value;
|
|
15
|
+
return (typeof candidate.id === 'string' &&
|
|
16
|
+
typeof candidate.jwe === 'object' &&
|
|
17
|
+
candidate.jwe !== null);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/edv/document.ts"],"names":[],"mappings":"AAgBA,yDAAyD;AACzD,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAA;AAKtD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAc;IAEd,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,SAAS,GAAG,KAAgC,CAAA;IAClD,OAAO,CACL,OAAO,SAAS,CAAC,EAAE,KAAK,QAAQ;QAChC,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ;QACjC,SAAS,CAAC,GAAG,KAAK,IAAI,CACvB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMAC key (`SHA256HMACKey`) resolution for EDV index blinding. The
|
|
3
|
+
* concrete key implementation -- the reference `IHMAC` impl -- lives in
|
|
4
|
+
* `@interop/data-integrity-core`; this module only adapts it to the CLI's
|
|
5
|
+
* wallet storage: it finds the blinding key the `edv encrypt --index` flow
|
|
6
|
+
* should use (by id, handle, or storage id, or by auto-selecting the lone HMAC
|
|
7
|
+
* key) and reconstructs it from its persisted JWK secret.
|
|
8
|
+
*/
|
|
9
|
+
import { SHA256HMACKey } from '@interop/data-integrity-core';
|
|
10
|
+
/** The stored `type` value of an HMAC blinding key (the EDV protocol string). */
|
|
11
|
+
export declare const HMAC_KEY_TYPE = "Sha256HmacKey2019";
|
|
12
|
+
/**
|
|
13
|
+
* Resolve the HMAC blinding key for index operations. With `ref`, match a
|
|
14
|
+
* stored HMAC key by its id, its storage id, or its metadata handle; without
|
|
15
|
+
* `ref`, auto-select when the wallet holds exactly one HMAC key. Throws with a
|
|
16
|
+
* clear message when nothing matches, the handle/ref is ambiguous, or no HMAC
|
|
17
|
+
* key exists yet.
|
|
18
|
+
*
|
|
19
|
+
* @param options {object}
|
|
20
|
+
* @param [options.ref] {string} The `--hmac` value; auto-select when omitted.
|
|
21
|
+
* @returns {Promise<SHA256HMACKey>}
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveHmac({ ref }: {
|
|
24
|
+
ref?: string;
|
|
25
|
+
}): Promise<SHA256HMACKey>;
|
|
26
|
+
//# sourceMappingURL=hmac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmac.d.ts","sourceRoot":"","sources":["../../src/edv/hmac.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EAEd,MAAM,8BAA8B,CAAA;AAOrC,iFAAiF;AACjF,eAAO,MAAM,aAAa,sBAAsB,CAAA;AAyBhD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,EAChC,GAAG,EACJ,EAAE;IACD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,aAAa,CAAC,CA+CzB"}
|
package/dist/edv/hmac.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMAC key (`SHA256HMACKey`) resolution for EDV index blinding. The
|
|
3
|
+
* concrete key implementation -- the reference `IHMAC` impl -- lives in
|
|
4
|
+
* `@interop/data-integrity-core`; this module only adapts it to the CLI's
|
|
5
|
+
* wallet storage: it finds the blinding key the `edv encrypt --index` flow
|
|
6
|
+
* should use (by id, handle, or storage id, or by auto-selecting the lone HMAC
|
|
7
|
+
* key) and reconstructs it from its persisted JWK secret.
|
|
8
|
+
*/
|
|
9
|
+
import { SHA256HMACKey } from '@interop/data-integrity-core';
|
|
10
|
+
import { listCollection, loadFromCollection, loadMetaFromCollection } from '../storage.js';
|
|
11
|
+
/** The stored `type` value of an HMAC blinding key (the EDV protocol string). */
|
|
12
|
+
export const HMAC_KEY_TYPE = 'Sha256HmacKey2019';
|
|
13
|
+
/**
|
|
14
|
+
* Collect every `SHA256HMACKey` stored in the wallet keys collection.
|
|
15
|
+
*
|
|
16
|
+
* @returns {Promise<StoredHmac[]>}
|
|
17
|
+
*/
|
|
18
|
+
async function listStoredHmacs() {
|
|
19
|
+
const storageIds = await listCollection('keys');
|
|
20
|
+
const stored = await Promise.all(storageIds.map(storageId => loadFromCollection('keys', storageId)));
|
|
21
|
+
return storageIds
|
|
22
|
+
.map((storageId, index) => ({ storageId, stored: stored[index] }))
|
|
23
|
+
.filter(({ stored }) => stored.type === HMAC_KEY_TYPE);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the HMAC blinding key for index operations. With `ref`, match a
|
|
27
|
+
* stored HMAC key by its id, its storage id, or its metadata handle; without
|
|
28
|
+
* `ref`, auto-select when the wallet holds exactly one HMAC key. Throws with a
|
|
29
|
+
* clear message when nothing matches, the handle/ref is ambiguous, or no HMAC
|
|
30
|
+
* key exists yet.
|
|
31
|
+
*
|
|
32
|
+
* @param options {object}
|
|
33
|
+
* @param [options.ref] {string} The `--hmac` value; auto-select when omitted.
|
|
34
|
+
* @returns {Promise<SHA256HMACKey>}
|
|
35
|
+
*/
|
|
36
|
+
export async function resolveHmac({ ref }) {
|
|
37
|
+
const candidates = await listStoredHmacs();
|
|
38
|
+
if (candidates.length === 0) {
|
|
39
|
+
throw new Error('No HMAC key found in the wallet; create one with ' +
|
|
40
|
+
'`di key create --type hmac --save`.');
|
|
41
|
+
}
|
|
42
|
+
if (ref === undefined) {
|
|
43
|
+
if (candidates.length > 1) {
|
|
44
|
+
throw new Error(`The wallet has ${candidates.length} HMAC keys; ` +
|
|
45
|
+
'pass --hmac to choose one.');
|
|
46
|
+
}
|
|
47
|
+
return SHA256HMACKey.from(candidates[0].stored);
|
|
48
|
+
}
|
|
49
|
+
const direct = candidates.find(candidate => candidate.stored.id === ref || candidate.storageId === ref);
|
|
50
|
+
if (direct) {
|
|
51
|
+
return SHA256HMACKey.from(direct.stored);
|
|
52
|
+
}
|
|
53
|
+
const metas = await Promise.all(candidates.map(candidate => loadMetaFromCollection({
|
|
54
|
+
collection: 'keys',
|
|
55
|
+
storageId: candidate.storageId
|
|
56
|
+
})));
|
|
57
|
+
const byHandle = candidates.filter((_candidate, index) => metas[index]?.handle === ref);
|
|
58
|
+
if (byHandle.length === 0) {
|
|
59
|
+
throw new Error(`No HMAC key found for "${ref}".`);
|
|
60
|
+
}
|
|
61
|
+
if (byHandle.length > 1) {
|
|
62
|
+
throw new Error(`Handle "${ref}" matches ${byHandle.length} HMAC keys; ` +
|
|
63
|
+
'use the key id instead.');
|
|
64
|
+
}
|
|
65
|
+
return SHA256HMACKey.from(byHandle[0].stored);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=hmac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hmac.js","sourceRoot":"","sources":["../../src/edv/hmac.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EAEd,MAAM,8BAA8B,CAAA;AACrC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,eAAe,CAAA;AAEtB,iFAAiF;AACjF,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAA;AAQhD;;;;GAIG;AACH,KAAK,UAAU,eAAe;IAC5B,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CACzB,kBAAkB,CAAiB,MAAM,EAAE,SAAS,CAAC,CACtD,CACF,CAAA;IACD,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SACjE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;AAC1D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAChC,GAAG,EAGJ;IACC,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAA;IAC1C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,mDAAmD;YACjD,qCAAqC,CACxC,CAAA;IACH,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACb,kBAAkB,UAAU,CAAC,MAAM,cAAc;gBAC/C,4BAA4B,CAC/B,CAAA;QACH,CAAC;QACD,OAAO,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAC5B,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,SAAS,CAAC,SAAS,KAAK,GAAG,CACxE,CAAA;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CACzB,sBAAsB,CAAC;QACrB,UAAU,EAAE,MAAM;QAClB,SAAS,EAAE,SAAS,CAAC,SAAS;KAC/B,CAAC,CACH,CACF,CAAA;IACD,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAChC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,GAAG,CACpD,CAAA;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAA;IACpD,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,WAAW,GAAG,aAAa,QAAQ,CAAC,MAAM,cAAc;YACtD,yBAAyB,CAC5B,CAAA;IACH,CAAC;IACD,OAAO,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAC/C,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key';
|
|
2
|
+
/** The X25519 key-agreement verification-method type minimal-cipher expects. */
|
|
3
|
+
export declare const KEY_AGREEMENT_TYPE = "X25519KeyAgreementKey2020";
|
|
4
|
+
/**
|
|
5
|
+
* An X25519 key-agreement key instance with its `.id` (`kid`) populated. Used
|
|
6
|
+
* both as a resolved recipient (encrypt reads `id` + `publicKeyMultibase`) and
|
|
7
|
+
* as the decryption key (decrypt reads `id` + `deriveSecret`).
|
|
8
|
+
*/
|
|
9
|
+
export type KeyAgreementKey = InstanceType<typeof X25519KeyAgreementKey2020> & {
|
|
10
|
+
id: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Resolve one `--recipient` value to a recipient key. Resolution order: a raw
|
|
14
|
+
* X25519 `publicKeyMultibase` (starts `z6LS`), then a DID / DID URL, then a
|
|
15
|
+
* wallet key fingerprint or handle.
|
|
16
|
+
*
|
|
17
|
+
* @param options {object}
|
|
18
|
+
* @param options.ref {string}
|
|
19
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveRecipient({ ref }: {
|
|
22
|
+
ref: string;
|
|
23
|
+
}): Promise<KeyAgreementKey>;
|
|
24
|
+
/**
|
|
25
|
+
* Load and validate a key-document JSON file holding an X25519 public key, and
|
|
26
|
+
* construct its key-agreement key.
|
|
27
|
+
*
|
|
28
|
+
* @param options {object}
|
|
29
|
+
* @param options.path {string}
|
|
30
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveRecipientFile({ path }: {
|
|
33
|
+
path: string;
|
|
34
|
+
}): Promise<KeyAgreementKey>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a `--key` reference (fingerprint or handle) to a reconstructed
|
|
37
|
+
* X25519 key-agreement key. The referenced key must be a stored X25519 key
|
|
38
|
+
* with its secret half.
|
|
39
|
+
*
|
|
40
|
+
* @param options {object}
|
|
41
|
+
* @param options.ref {string}
|
|
42
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
43
|
+
*/
|
|
44
|
+
export declare function loadKeyAgreementKey({ ref }: {
|
|
45
|
+
ref: string;
|
|
46
|
+
}): Promise<KeyAgreementKey>;
|
|
47
|
+
/**
|
|
48
|
+
* Auto-select the decryption key when `--key` is omitted: scan the stored
|
|
49
|
+
* X25519 secret keys and return the one whose `id` (`kid`) matches a recipient
|
|
50
|
+
* of the JWE. Throws when none match or more than one does.
|
|
51
|
+
*
|
|
52
|
+
* @param options {object}
|
|
53
|
+
* @param options.jwe {{recipients?: {header?: {kid?: string}}[]}}
|
|
54
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
55
|
+
*/
|
|
56
|
+
export declare function autoSelectKeyAgreementKey({ jwe }: {
|
|
57
|
+
jwe: {
|
|
58
|
+
recipients?: {
|
|
59
|
+
header?: {
|
|
60
|
+
kid?: string;
|
|
61
|
+
};
|
|
62
|
+
}[];
|
|
63
|
+
};
|
|
64
|
+
}): Promise<KeyAgreementKey>;
|
|
65
|
+
//# sourceMappingURL=recipients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.d.ts","sourceRoot":"","sources":["../../src/edv/recipients.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAI7E,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,8BAA8B,CAAA;AAW7D;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO,yBAAyB,CAAC,GAAG;IAC7E,EAAE,EAAE,MAAM,CAAA;CACX,CAAA;AAqKD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,GAAG,EACJ,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,OAAO,CAAC,eAAe,CAAC,CAmB3B;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,EACzC,IAAI,EACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,OAAO,CAAC,eAAe,CAAC,CAa3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,GAAG,EACJ,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,OAAO,CAAC,eAAe,CAAC,CAa3B;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,GAAG,EACJ,EAAE;IACD,GAAG,EAAE;QAAE,UAAU,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE;gBAAE,GAAG,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,EAAE,CAAA;KAAE,CAAA;CACtD,GAAG,OAAO,CAAC,eAAe,CAAC,CAsC3B"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recipient and key-agreement resolution for the `edv encrypt`/`edv decrypt`
|
|
3
|
+
* commands. Normalizes the several recipient reference forms (a raw X25519
|
|
4
|
+
* `publicKeyMultibase`, a wallet key fingerprint or handle, a DID or DID URL,
|
|
5
|
+
* and a key-document JSON file) into `X25519KeyAgreementKey2020` instances --
|
|
6
|
+
* the shape `@interop/minimal-cipher`'s `keyResolver` returns (the cipher reads
|
|
7
|
+
* `id` and `publicKeyMultibase` from a recipient on encrypt, and `id` and
|
|
8
|
+
* `deriveSecret` from the key on decrypt, all of which an instance provides).
|
|
9
|
+
* Builds the recipients array plus that resolver, and reconstructs stored keys
|
|
10
|
+
* for decrypt.
|
|
11
|
+
*/
|
|
12
|
+
import { readFile } from 'node:fs/promises';
|
|
13
|
+
import { securityLoader } from '@interop/security-document-loader';
|
|
14
|
+
import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key';
|
|
15
|
+
import { listCollection, loadFromCollection } from '../storage.js';
|
|
16
|
+
import { resolveKeyRef } from '../meta.js';
|
|
17
|
+
/** The X25519 key-agreement verification-method type minimal-cipher expects. */
|
|
18
|
+
export const KEY_AGREEMENT_TYPE = 'X25519KeyAgreementKey2020';
|
|
19
|
+
/**
|
|
20
|
+
* Document loader for DID-URL recipient resolution: resolves a bare DID to its
|
|
21
|
+
* DID document and dereferences a `did#fragment` URL straight to its
|
|
22
|
+
* verification-method node, for both did:key (offline) and did:web (fetched).
|
|
23
|
+
* Built once and reused. (Per project convention, DID/JSON-LD resolution goes
|
|
24
|
+
* through `@interop/security-document-loader`, never a hand-rolled loader.)
|
|
25
|
+
*/
|
|
26
|
+
const documentLoader = securityLoader().build();
|
|
27
|
+
/**
|
|
28
|
+
* Construct an X25519 key-agreement key from a verification method or stored
|
|
29
|
+
* key pair. `didKey: true` defaults a source with no `controller`/`id` to its
|
|
30
|
+
* `did:key` form, so the key class derives `.id` as `did:key:<mb>#<mb>` -- the
|
|
31
|
+
* `kid` encrypt and decrypt both match on -- while a source that already
|
|
32
|
+
* carries an `id`/`controller` (e.g. a DID verification method) keeps it. A
|
|
33
|
+
* `type: 'Multikey'` source is normalized via `fromMultikey`. The constructor
|
|
34
|
+
* validates the multibase header bytes.
|
|
35
|
+
*
|
|
36
|
+
* @param source {Record<string, any>}
|
|
37
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
38
|
+
*/
|
|
39
|
+
async function keyAgreementKeyFrom(source) {
|
|
40
|
+
const key = await X25519KeyAgreementKey2020.from({ didKey: true, ...source });
|
|
41
|
+
return key;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Split a DID URL into its base DID and `#fragment` (undefined when absent).
|
|
45
|
+
*
|
|
46
|
+
* @param options {object}
|
|
47
|
+
* @param options.ref {string}
|
|
48
|
+
* @returns {{did: string, fragment?: string}}
|
|
49
|
+
*/
|
|
50
|
+
function splitFragment({ ref }) {
|
|
51
|
+
const hash = ref.indexOf('#');
|
|
52
|
+
if (hash === -1) {
|
|
53
|
+
return { did: ref };
|
|
54
|
+
}
|
|
55
|
+
return { did: ref.slice(0, hash), fragment: ref.slice(hash + 1) };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a DID URL through the security document loader. A bare DID resolves
|
|
59
|
+
* to its DID document; a `did#fragment` URL is dereferenced straight to its
|
|
60
|
+
* verification-method node.
|
|
61
|
+
*
|
|
62
|
+
* @param options {object}
|
|
63
|
+
* @param options.url {string}
|
|
64
|
+
* @returns {Promise<Record<string, any>>}
|
|
65
|
+
*/
|
|
66
|
+
async function resolveDidUrl({ url }) {
|
|
67
|
+
const { document } = (await documentLoader(url));
|
|
68
|
+
return document;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* True when a `publicKeyMultibase` carries the X25519 multicodec header. This
|
|
72
|
+
* is the type-agnostic discriminator for a usable key-agreement key: it accepts
|
|
73
|
+
* both an `X25519KeyAgreementKey2020` and a `Multikey` whose key is X25519,
|
|
74
|
+
* while rejecting an Ed25519/other key, regardless of the `type` string a DID
|
|
75
|
+
* document happens to use.
|
|
76
|
+
*
|
|
77
|
+
* @param publicKeyMultibase {string | undefined}
|
|
78
|
+
* @returns {boolean}
|
|
79
|
+
*/
|
|
80
|
+
function isX25519PublicKey(publicKeyMultibase) {
|
|
81
|
+
if (!publicKeyMultibase) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
// The constructor validates the X25519 header bytes and throws otherwise.
|
|
86
|
+
X25519KeyAgreementKey2020.fromFingerprint({
|
|
87
|
+
fingerprint: publicKeyMultibase
|
|
88
|
+
});
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Validate that a verification method is a usable X25519 key-agreement key
|
|
97
|
+
* (an `X25519KeyAgreementKey2020` or a `Multikey` whose public key is X25519)
|
|
98
|
+
* and construct it.
|
|
99
|
+
*
|
|
100
|
+
* @param options {object}
|
|
101
|
+
* @param options.method {Record<string, any>}
|
|
102
|
+
* @param options.ref {string}
|
|
103
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
104
|
+
*/
|
|
105
|
+
async function toKeyAgreementKey({ method, ref }) {
|
|
106
|
+
if (!isX25519PublicKey(method.publicKeyMultibase)) {
|
|
107
|
+
throw new Error(`Recipient "${ref}" is not an ${KEY_AGREEMENT_TYPE} key.`);
|
|
108
|
+
}
|
|
109
|
+
return keyAgreementKeyFrom(method);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Resolve a DID or DID URL recipient to its X25519 key-agreement key. A bare
|
|
113
|
+
* DID with a single keyAgreement key uses that key; one with several requires
|
|
114
|
+
* the `#fragment` form to disambiguate.
|
|
115
|
+
*
|
|
116
|
+
* @param options {object}
|
|
117
|
+
* @param options.ref {string}
|
|
118
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
119
|
+
*/
|
|
120
|
+
async function resolveDidRecipient({ ref }) {
|
|
121
|
+
const { did, fragment } = splitFragment({ ref });
|
|
122
|
+
// A fragment URL dereferences straight to its verification-method node.
|
|
123
|
+
if (fragment !== undefined) {
|
|
124
|
+
return toKeyAgreementKey({ method: await resolveDidUrl({ url: ref }), ref });
|
|
125
|
+
}
|
|
126
|
+
// A bare DID: pick the single keyAgreement key, dereferencing any entries
|
|
127
|
+
// that are id references rather than embedded verification methods.
|
|
128
|
+
const didDocument = await resolveDidUrl({ url: did });
|
|
129
|
+
const entries = (didDocument.keyAgreement ?? []);
|
|
130
|
+
const methods = [];
|
|
131
|
+
for (const entry of entries) {
|
|
132
|
+
methods.push(typeof entry === 'string' ? await resolveDidUrl({ url: entry }) : entry);
|
|
133
|
+
}
|
|
134
|
+
const usable = methods.filter(method => method.type === KEY_AGREEMENT_TYPE && method.publicKeyMultibase);
|
|
135
|
+
if (usable.length === 0) {
|
|
136
|
+
throw new Error(`DID ${did} has no ${KEY_AGREEMENT_TYPE} keyAgreement key.`);
|
|
137
|
+
}
|
|
138
|
+
if (usable.length > 1) {
|
|
139
|
+
throw new Error(`DID ${did} has ${usable.length} keyAgreement keys; ` +
|
|
140
|
+
'use the did#fragment form to choose one.');
|
|
141
|
+
}
|
|
142
|
+
return toKeyAgreementKey({ method: usable[0], ref });
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Resolve one `--recipient` value to a recipient key. Resolution order: a raw
|
|
146
|
+
* X25519 `publicKeyMultibase` (starts `z6LS`), then a DID / DID URL, then a
|
|
147
|
+
* wallet key fingerprint or handle.
|
|
148
|
+
*
|
|
149
|
+
* @param options {object}
|
|
150
|
+
* @param options.ref {string}
|
|
151
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
152
|
+
*/
|
|
153
|
+
export async function resolveRecipient({ ref }) {
|
|
154
|
+
if (ref.startsWith('z6LS')) {
|
|
155
|
+
return toKeyAgreementKey({
|
|
156
|
+
method: { type: KEY_AGREEMENT_TYPE, publicKeyMultibase: ref },
|
|
157
|
+
ref
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
if (ref.startsWith('did:')) {
|
|
161
|
+
return resolveDidRecipient({ ref });
|
|
162
|
+
}
|
|
163
|
+
const resolved = await resolveKeyRef({ ref });
|
|
164
|
+
if (!resolved?.key.publicKeyMultibase) {
|
|
165
|
+
throw new Error(`Could not resolve recipient "${ref}".`);
|
|
166
|
+
}
|
|
167
|
+
const stored = resolved.key;
|
|
168
|
+
if (stored.type !== KEY_AGREEMENT_TYPE) {
|
|
169
|
+
throw new Error(`Wallet key "${ref}" is not an ${KEY_AGREEMENT_TYPE} key.`);
|
|
170
|
+
}
|
|
171
|
+
return keyAgreementKeyFrom(stored);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Load and validate a key-document JSON file holding an X25519 public key, and
|
|
175
|
+
* construct its key-agreement key.
|
|
176
|
+
*
|
|
177
|
+
* @param options {object}
|
|
178
|
+
* @param options.path {string}
|
|
179
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
180
|
+
*/
|
|
181
|
+
export async function resolveRecipientFile({ path }) {
|
|
182
|
+
let method;
|
|
183
|
+
try {
|
|
184
|
+
method = JSON.parse(await readFile(path, 'utf8'));
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
throw new Error(`Could not read key document "${path}": ${err.message}`, {
|
|
188
|
+
cause: err
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return toKeyAgreementKey({ method, ref: path });
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Resolve a `--key` reference (fingerprint or handle) to a reconstructed
|
|
195
|
+
* X25519 key-agreement key. The referenced key must be a stored X25519 key
|
|
196
|
+
* with its secret half.
|
|
197
|
+
*
|
|
198
|
+
* @param options {object}
|
|
199
|
+
* @param options.ref {string}
|
|
200
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
201
|
+
*/
|
|
202
|
+
export async function loadKeyAgreementKey({ ref }) {
|
|
203
|
+
const resolved = await resolveKeyRef({ ref });
|
|
204
|
+
if (!resolved) {
|
|
205
|
+
throw new Error(`No locally stored key found for "${ref}".`);
|
|
206
|
+
}
|
|
207
|
+
const stored = resolved.key;
|
|
208
|
+
if (stored.type !== KEY_AGREEMENT_TYPE) {
|
|
209
|
+
throw new Error(`Wallet key "${ref}" is not an ${KEY_AGREEMENT_TYPE} key.`);
|
|
210
|
+
}
|
|
211
|
+
if (!stored.privateKeyMultibase) {
|
|
212
|
+
throw new Error(`Wallet key "${ref}" has no secret key to decrypt with.`);
|
|
213
|
+
}
|
|
214
|
+
return keyAgreementKeyFrom(stored);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Auto-select the decryption key when `--key` is omitted: scan the stored
|
|
218
|
+
* X25519 secret keys and return the one whose `id` (`kid`) matches a recipient
|
|
219
|
+
* of the JWE. Throws when none match or more than one does.
|
|
220
|
+
*
|
|
221
|
+
* @param options {object}
|
|
222
|
+
* @param options.jwe {{recipients?: {header?: {kid?: string}}[]}}
|
|
223
|
+
* @returns {Promise<KeyAgreementKey>}
|
|
224
|
+
*/
|
|
225
|
+
export async function autoSelectKeyAgreementKey({ jwe }) {
|
|
226
|
+
const kids = new Set((jwe.recipients ?? [])
|
|
227
|
+
.map(recipient => recipient?.header?.kid)
|
|
228
|
+
.filter((kid) => typeof kid === 'string'));
|
|
229
|
+
const storageIds = await listCollection('keys');
|
|
230
|
+
const matches = [];
|
|
231
|
+
for (const storageId of storageIds) {
|
|
232
|
+
const stored = await loadFromCollection('keys', storageId);
|
|
233
|
+
if (stored.type !== KEY_AGREEMENT_TYPE ||
|
|
234
|
+
!stored.privateKeyMultibase ||
|
|
235
|
+
!stored.publicKeyMultibase) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const key = await keyAgreementKeyFrom(stored);
|
|
239
|
+
if (kids.has(key.id)) {
|
|
240
|
+
matches.push(key);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (matches.length === 0) {
|
|
244
|
+
throw new Error('No stored X25519 key matches any recipient of this JWE; ' +
|
|
245
|
+
'pass --key to choose one.');
|
|
246
|
+
}
|
|
247
|
+
if (matches.length > 1) {
|
|
248
|
+
throw new Error(`${matches.length} stored X25519 keys match this JWE; ` +
|
|
249
|
+
'pass --key to choose one.');
|
|
250
|
+
}
|
|
251
|
+
return matches[0];
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=recipients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.js","sourceRoot":"","sources":["../../src/edv/recipients.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Cipher } from '@interop/minimal-cipher';
|
|
2
|
+
import type { IEDVChunk, IEncryptedDocument, IKeyResolver, IRecipientTemplate } from '@interop/data-integrity-core';
|
|
3
|
+
import type { KeyAgreementKey } from './recipients.js';
|
|
4
|
+
/**
|
|
5
|
+
* Encrypt `data` as a stream of chunks for the given recipients, stamping the
|
|
6
|
+
* document `sequence` onto each chunk (as `EdvClientCore._updateStream` does).
|
|
7
|
+
*
|
|
8
|
+
* @param options {object}
|
|
9
|
+
* @param options.cipher {Cipher}
|
|
10
|
+
* @param options.data {Uint8Array}
|
|
11
|
+
* @param options.recipients {IRecipientTemplate[]}
|
|
12
|
+
* @param options.keyResolver {IKeyResolver}
|
|
13
|
+
* @param [options.chunkSize] {number} Bytes per chunk (cipher default 1 MiB).
|
|
14
|
+
* @param options.sequence {number} The owning document's sequence.
|
|
15
|
+
* @returns {Promise<IEDVChunk[]>}
|
|
16
|
+
*/
|
|
17
|
+
export declare function encryptToChunks({ cipher, data, recipients, keyResolver, chunkSize, sequence }: {
|
|
18
|
+
cipher: Cipher;
|
|
19
|
+
data: Uint8Array;
|
|
20
|
+
recipients: IRecipientTemplate[];
|
|
21
|
+
keyResolver: IKeyResolver;
|
|
22
|
+
chunkSize?: number;
|
|
23
|
+
sequence: number;
|
|
24
|
+
}): Promise<IEDVChunk[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Decrypt a document's chunks (in `index` order) back into the original bytes.
|
|
27
|
+
* A wrong key surfaces as a thrown `DataError` from the decrypt transformer.
|
|
28
|
+
*
|
|
29
|
+
* @param options {object}
|
|
30
|
+
* @param options.cipher {Cipher}
|
|
31
|
+
* @param options.chunks {IEDVChunk[]}
|
|
32
|
+
* @param options.keyAgreementKey {KeyAgreementKey}
|
|
33
|
+
* @returns {Promise<Uint8Array>}
|
|
34
|
+
*/
|
|
35
|
+
export declare function decryptChunks({ cipher, chunks, keyAgreementKey }: {
|
|
36
|
+
cipher: Cipher;
|
|
37
|
+
chunks: IEDVChunk[];
|
|
38
|
+
keyAgreementKey: KeyAgreementKey;
|
|
39
|
+
}): Promise<Uint8Array>;
|
|
40
|
+
/**
|
|
41
|
+
* Write a streamed EDV Document as a bundle directory: `document.json` plus
|
|
42
|
+
* `chunks/<index>.jwe.json` for each chunk.
|
|
43
|
+
*
|
|
44
|
+
* @param options {object}
|
|
45
|
+
* @param options.dir {string} The bundle directory path.
|
|
46
|
+
* @param options.document {IEncryptedDocument}
|
|
47
|
+
* @param options.chunks {IEDVChunk[]}
|
|
48
|
+
* @returns {Promise<void>}
|
|
49
|
+
*/
|
|
50
|
+
export declare function writeDocumentBundle({ dir, document, chunks }: {
|
|
51
|
+
dir: string;
|
|
52
|
+
document: IEncryptedDocument;
|
|
53
|
+
chunks: IEDVChunk[];
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Read a bundle directory back into its document envelope and chunks (sorted by
|
|
57
|
+
* `index`).
|
|
58
|
+
*
|
|
59
|
+
* @param options {object}
|
|
60
|
+
* @param options.dir {string} The bundle directory path.
|
|
61
|
+
* @returns {Promise<{document: IEncryptedDocument, chunks: IEDVChunk[]}>}
|
|
62
|
+
*/
|
|
63
|
+
export declare function readDocumentBundle({ dir }: {
|
|
64
|
+
dir: string;
|
|
65
|
+
}): Promise<{
|
|
66
|
+
document: IEncryptedDocument;
|
|
67
|
+
chunks: IEDVChunk[];
|
|
68
|
+
}>;
|
|
69
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/edv/stream.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,KAAK,EACV,SAAS,EACT,kBAAkB,EAElB,YAAY,EACZ,kBAAkB,EACnB,MAAM,8BAA8B,CAAA;AAErC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AA6DtD;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CAAC,EACpC,MAAM,EACN,IAAI,EACJ,UAAU,EACV,WAAW,EACX,SAAS,EACT,QAAQ,EACT,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,UAAU,CAAA;IAChB,UAAU,EAAE,kBAAkB,EAAE,CAAA;IAChC,WAAW,EAAE,YAAY,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAgBvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,EAClC,MAAM,EACN,MAAM,EACN,eAAe,EAChB,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,eAAe,EAAE,eAAe,CAAA;CACjC,GAAG,OAAO,CAAC,UAAU,CAAC,CAUtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,EACxC,GAAG,EACH,QAAQ,EACR,MAAM,EACP,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,MAAM,EAAE,SAAS,EAAE,CAAA;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAehB;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,GAAG,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAC1E,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,MAAM,EAAE,SAAS,EAAE,CAAA;CACpB,CAAC,CA0BD"}
|