@interop/wallet-core 0.14.0 → 0.16.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 -4
- package/dist/clients/index.d.ts +32 -0
- package/dist/clients/index.d.ts.map +1 -0
- package/dist/clients/index.js +28 -0
- package/dist/clients/index.js.map +1 -0
- package/dist/clients/listing.d.ts +103 -0
- package/dist/clients/listing.d.ts.map +1 -0
- package/dist/clients/listing.js +86 -0
- package/dist/clients/listing.js.map +1 -0
- package/dist/clients/policy.d.ts +79 -0
- package/dist/clients/policy.d.ts.map +1 -0
- package/dist/clients/policy.js +55 -0
- package/dist/clients/policy.js.map +1 -0
- package/dist/clients/revocation.d.ts +156 -0
- package/dist/clients/revocation.d.ts.map +1 -0
- package/dist/clients/revocation.js +142 -0
- package/dist/clients/revocation.js.map +1 -0
- package/dist/clients/rosterPolicy.d.ts +124 -0
- package/dist/clients/rosterPolicy.d.ts.map +1 -0
- package/dist/clients/rosterPolicy.js +125 -0
- package/dist/clients/rosterPolicy.js.map +1 -0
- package/dist/enrollment/connectCode.d.ts +29 -0
- package/dist/enrollment/connectCode.d.ts.map +1 -0
- package/dist/enrollment/connectCode.js +31 -0
- package/dist/enrollment/connectCode.js.map +1 -0
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +1 -5
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/enrollment/index.d.ts +3 -0
- package/dist/enrollment/index.d.ts.map +1 -1
- package/dist/enrollment/index.js +3 -0
- package/dist/enrollment/index.js.map +1 -1
- package/dist/keys/clientKeyRecord.d.ts +124 -0
- package/dist/keys/clientKeyRecord.d.ts.map +1 -0
- package/dist/keys/clientKeyRecord.js +265 -0
- package/dist/keys/clientKeyRecord.js.map +1 -0
- package/dist/keys/index.d.ts +5 -0
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +4 -0
- package/dist/keys/index.js.map +1 -1
- package/dist/request/index.d.ts +4 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +4 -0
- package/dist/request/index.js.map +1 -1
- package/dist/request/walletInput.d.ts +93 -0
- package/dist/request/walletInput.d.ts.map +1 -0
- package/dist/request/walletInput.js +182 -0
- package/dist/request/walletInput.js.map +1 -0
- package/dist/sync/contactsConflict.d.ts +76 -0
- package/dist/sync/contactsConflict.d.ts.map +1 -0
- package/dist/sync/contactsConflict.js +95 -0
- package/dist/sync/contactsConflict.js.map +1 -0
- package/dist/sync/index.d.ts +5 -0
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +4 -0
- package/dist/sync/index.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +6 -0
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +16 -0
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +5 -2
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +4 -1
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts +58 -0
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +54 -0
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +6 -0
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +6 -0
- package/dist/webvh/revokeClient.js.map +1 -1
- package/package.json +15 -2
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { ClientWebvhUpdateKeys } from '../webvh/didWebvh.js';
|
|
2
|
+
import type { Puk } from './puk.js';
|
|
3
|
+
/**
|
|
4
|
+
* A client-key record's contents, decoded.
|
|
5
|
+
*
|
|
6
|
+
* `clientSeed` is the only always-present member: the rest are absent on
|
|
7
|
+
* records written before that member existed (a PUK-less account, a record
|
|
8
|
+
* written before the update keys became client-held, a first client whose own
|
|
9
|
+
* did:key IS the account controller), or simply not stored by the app.
|
|
10
|
+
*/
|
|
11
|
+
export interface ClientKeyRecord {
|
|
12
|
+
clientSeed: Uint8Array;
|
|
13
|
+
puk?: Puk;
|
|
14
|
+
webvhUpdateKeys?: ClientWebvhUpdateKeys;
|
|
15
|
+
controller?: string;
|
|
16
|
+
pointerDid?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A client-key record's contents as they are stored: plain JSON, every byte
|
|
20
|
+
* field base64url-encoded without padding. This is what an app wraps, seals,
|
|
21
|
+
* or stringifies -- the codec never decides where it goes.
|
|
22
|
+
*/
|
|
23
|
+
export interface ClientKeyRecordJson {
|
|
24
|
+
clientSeed: string;
|
|
25
|
+
puk?: {
|
|
26
|
+
id: string;
|
|
27
|
+
secret: string;
|
|
28
|
+
signingSeed?: string;
|
|
29
|
+
};
|
|
30
|
+
webvh?: {
|
|
31
|
+
updateSeed: string;
|
|
32
|
+
stagedSeed: string;
|
|
33
|
+
pendingStagedSeed?: string;
|
|
34
|
+
};
|
|
35
|
+
controller?: string;
|
|
36
|
+
pointerDid?: string;
|
|
37
|
+
createdAt?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
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 PUK, its own
|
|
42
|
+
* update-key seeds, and the account it belongs to).
|
|
43
|
+
*/
|
|
44
|
+
export interface EnrolledClientKeyRecord extends ClientKeyRecord {
|
|
45
|
+
puk: Puk;
|
|
46
|
+
webvhUpdateKeys: ClientWebvhUpdateKeys;
|
|
47
|
+
controller: string;
|
|
48
|
+
pointerDid: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parses and validates the optional `puk` member. An absent member resolves to
|
|
52
|
+
* `undefined` (a record written for an account minted before the PUK); a
|
|
53
|
+
* present-but-malformed one throws.
|
|
54
|
+
*
|
|
55
|
+
* The signing seed is absent on a PUK adopted from a roster rotation (the
|
|
56
|
+
* roster wraps the key-agreement secret alone); when present it must be
|
|
57
|
+
* well-formed.
|
|
58
|
+
*
|
|
59
|
+
* @param value {unknown} the record's `puk` member
|
|
60
|
+
* @returns {Puk | undefined}
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseClientRecordPuk(value: unknown): Puk | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Parses and validates the optional `webvh` member: this client's did:webvh
|
|
65
|
+
* update-key seeds. An absent member resolves to `undefined` (a record written
|
|
66
|
+
* before the update keys became client-held); a present-but-malformed one
|
|
67
|
+
* throws.
|
|
68
|
+
*
|
|
69
|
+
* @param value {unknown} the record's `webvh` member
|
|
70
|
+
* @returns {ClientWebvhUpdateKeys | undefined}
|
|
71
|
+
*/
|
|
72
|
+
export declare function parseClientRecordWebvhKeys(value: unknown): ClientWebvhUpdateKeys | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Encodes a client-key record's contents for storage: base64url byte fields,
|
|
75
|
+
* optional members omitted rather than written as null.
|
|
76
|
+
*
|
|
77
|
+
* @param options {object}
|
|
78
|
+
* @param options.clientSeed {Uint8Array} this client's 32-byte seed
|
|
79
|
+
* @param [options.puk] {Puk} the cached per-user key
|
|
80
|
+
* @param [options.webvhUpdateKeys] {ClientWebvhUpdateKeys} this client's
|
|
81
|
+
* did:webvh update-key seeds
|
|
82
|
+
* @param [options.controller] {string} the account controller this key set
|
|
83
|
+
* was bound for -- on an enrolled (non-first) client it differs from the
|
|
84
|
+
* client's own did:key
|
|
85
|
+
* @param [options.pointerDid] {string} the account's did:webvh
|
|
86
|
+
* @param [options.createdAt] {string} when the record was written; defaults
|
|
87
|
+
* to now
|
|
88
|
+
* @returns {ClientKeyRecordJson}
|
|
89
|
+
*/
|
|
90
|
+
export declare function encodeClientKeyRecord({ clientSeed, puk, webvhUpdateKeys, controller, pointerDid, createdAt }: {
|
|
91
|
+
clientSeed: Uint8Array;
|
|
92
|
+
puk?: Puk;
|
|
93
|
+
webvhUpdateKeys?: ClientWebvhUpdateKeys;
|
|
94
|
+
controller?: string;
|
|
95
|
+
pointerDid?: string;
|
|
96
|
+
createdAt?: string;
|
|
97
|
+
}): ClientKeyRecordJson;
|
|
98
|
+
/**
|
|
99
|
+
* Decodes and validates a stored client-key record's contents. Throws on any
|
|
100
|
+
* malformed member -- see the module doc for why nothing here is tolerated
|
|
101
|
+
* into a degraded record.
|
|
102
|
+
*
|
|
103
|
+
* @param options {object}
|
|
104
|
+
* @param options.contents {unknown} the stored JSON contents (an app that
|
|
105
|
+
* stores a string parses it first)
|
|
106
|
+
* @returns {ClientKeyRecord}
|
|
107
|
+
*/
|
|
108
|
+
export declare function decodeClientKeyRecord({ contents }: {
|
|
109
|
+
contents: unknown;
|
|
110
|
+
}): ClientKeyRecord;
|
|
111
|
+
/**
|
|
112
|
+
* Narrows a decoded record to a complete enrolled-client key set, throwing
|
|
113
|
+
* when any member an enrolled client needs is absent. For an app whose stored
|
|
114
|
+
* records are only ever written by the enrollment ceremony, this turns "the
|
|
115
|
+
* codec tolerates older records" into a single checked boundary.
|
|
116
|
+
*
|
|
117
|
+
* @param options {object}
|
|
118
|
+
* @param options.record {ClientKeyRecord}
|
|
119
|
+
* @returns {EnrolledClientKeyRecord}
|
|
120
|
+
*/
|
|
121
|
+
export declare function assertEnrolledClientKeyRecord({ record }: {
|
|
122
|
+
record: ClientKeyRecord;
|
|
123
|
+
}): EnrolledClientKeyRecord;
|
|
124
|
+
//# sourceMappingURL=clientKeyRecord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientKeyRecord.d.ts","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAOnC;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,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,GAAG,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1D,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,GAAG,EAAE,GAAG,CAAA;IACR,eAAe,EAAE,qBAAqB,CAAA;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB;AAkCD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,GAAG,SAAS,CA2BpE;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,qBAAqB,GAAG,SAAS,CA8BnC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EACV,GAAG,EACH,eAAe,EACf,UAAU,EACV,UAAU,EACV,SAAoC,EACrC,EAAE;IACD,UAAU,EAAE,UAAU,CAAA;IACtB,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,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,CAsCtB;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"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* The client-key record: the contents codec and validation for the local
|
|
6
|
+
* record every wallet client keeps its own key material in -- the random
|
|
7
|
+
* 32-byte client seed behind its Ed25519 signing key and X25519 twin, the
|
|
8
|
+
* cached per-user key (PUK) delivered through the wrap-set roster, this
|
|
9
|
+
* client's own did:webvh update-key seeds, the account controller the record
|
|
10
|
+
* was bound for, and (when the app stores it beside the keys) the account's
|
|
11
|
+
* did:webvh pointer.
|
|
12
|
+
*
|
|
13
|
+
* Only the CONTENTS live here. Where the record is stored, and what wraps it,
|
|
14
|
+
* stay with the app: a browser wallet wraps it under its unlock layer and puts
|
|
15
|
+
* it in local storage, a mobile wallet puts the encoded JSON in an encrypted
|
|
16
|
+
* database column. Both encode and validate identically, so a record one
|
|
17
|
+
* wallet writes is a record the other accepts.
|
|
18
|
+
*
|
|
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
|
+
* strict on purpose: an absent optional member is a record written before that
|
|
22
|
+
* member existed, but a present-and-malformed one throws, because both of the
|
|
23
|
+
* members that can be malformed are load-bearing -- the account's encrypted
|
|
24
|
+
* collections are keyed on the PUK, and the account's identity log can only be
|
|
25
|
+
* extended with the update-key seeds, so proceeding without either would
|
|
26
|
+
* silently orphan data or strand update authority.
|
|
27
|
+
*
|
|
28
|
+
* Two ordering invariants govern how an app persists what this codec encodes.
|
|
29
|
+
* Neither is enforceable here (the writes are the app's), and both are
|
|
30
|
+
* durability rules a crash must not be able to break:
|
|
31
|
+
*
|
|
32
|
+
* 1. **The PUK and the roster epoch pin persist atomically.** The pin is what
|
|
33
|
+
* refuses a rolled-back roster, so it must never advance without the key
|
|
34
|
+
* that authenticated the roster it advanced to -- and the key must never be
|
|
35
|
+
* adopted without the pin moving with it. One write, or none.
|
|
36
|
+
* 2. **Rolled update-key seeds persist BEFORE the log entry that publishes
|
|
37
|
+
* them.** A did:webvh rotation writes `pendingStagedSeed` (and the rolled
|
|
38
|
+
* `updateSeed` / `stagedSeed`) first and publishes second: a tear after the
|
|
39
|
+
* persist costs an unused staged key, while a tear after the publish would
|
|
40
|
+
* strand the log with an update key this client no longer holds -- an
|
|
41
|
+
* account that can never be updated again.
|
|
42
|
+
*
|
|
43
|
+
* This module is a LEAF, exported as `@interop/wallet-core/keys/clientKeyRecord`
|
|
44
|
+
* as well as through the `keys` subpath. Encoding a record is something the
|
|
45
|
+
* storage layer does, far from any key operation, so it imports only a base64url
|
|
46
|
+
* codec (its two key types are type-only imports, erased at compile time) and
|
|
47
|
+
* reaches nothing in the crypto / EDV graph. A wallet whose storage tests run
|
|
48
|
+
* without that graph loaded imports the leaf path directly.
|
|
49
|
+
*/
|
|
50
|
+
import { base64urlnopad } from '@scure/base';
|
|
51
|
+
/**
|
|
52
|
+
* The number of bytes every secret in the record carries.
|
|
53
|
+
*/
|
|
54
|
+
const SECRET_BYTES = 32;
|
|
55
|
+
/**
|
|
56
|
+
* Decodes one base64url byte field, checking its length.
|
|
57
|
+
*
|
|
58
|
+
* @param options {object}
|
|
59
|
+
* @param options.value {unknown} the encoded member
|
|
60
|
+
* @param options.name {string} the member's name, for the error message
|
|
61
|
+
* @returns {Uint8Array}
|
|
62
|
+
*/
|
|
63
|
+
function decodeSecret({ value, name }) {
|
|
64
|
+
if (typeof value !== 'string') {
|
|
65
|
+
throw new Error(`Client-key record ${name} is missing.`);
|
|
66
|
+
}
|
|
67
|
+
let bytes;
|
|
68
|
+
try {
|
|
69
|
+
bytes = base64urlnopad.decode(value);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw new Error(`Client-key record ${name} is not base64url.`, {
|
|
73
|
+
cause: err
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (bytes.length !== SECRET_BYTES) {
|
|
77
|
+
throw new Error(`Client-key record ${name} is not ${SECRET_BYTES} bytes.`);
|
|
78
|
+
}
|
|
79
|
+
return bytes;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Parses and validates the optional `puk` member. An absent member resolves to
|
|
83
|
+
* `undefined` (a record written for an account minted before the PUK); a
|
|
84
|
+
* present-but-malformed one throws.
|
|
85
|
+
*
|
|
86
|
+
* The signing seed is absent on a PUK adopted from a roster rotation (the
|
|
87
|
+
* roster wraps the key-agreement secret alone); when present it must be
|
|
88
|
+
* well-formed.
|
|
89
|
+
*
|
|
90
|
+
* @param value {unknown} the record's `puk` member
|
|
91
|
+
* @returns {Puk | undefined}
|
|
92
|
+
*/
|
|
93
|
+
export function parseClientRecordPuk(value) {
|
|
94
|
+
if (value === undefined) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
if (value === null || typeof value !== 'object') {
|
|
98
|
+
throw new Error('Client-key record has a malformed PUK.');
|
|
99
|
+
}
|
|
100
|
+
const { id, secret, signingSeed } = value;
|
|
101
|
+
if (typeof id !== 'string' || !id) {
|
|
102
|
+
throw new Error('Client-key record PUK is missing its key id.');
|
|
103
|
+
}
|
|
104
|
+
const secretBytes = decodeSecret({ value: secret, name: 'PUK key material' });
|
|
105
|
+
if (signingSeed === undefined) {
|
|
106
|
+
return { id, secret: secretBytes };
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
id,
|
|
110
|
+
secret: secretBytes,
|
|
111
|
+
signingSeed: decodeSecret({
|
|
112
|
+
value: signingSeed,
|
|
113
|
+
name: 'PUK signing seed'
|
|
114
|
+
})
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Parses and validates the optional `webvh` member: this client's did:webvh
|
|
119
|
+
* update-key seeds. An absent member resolves to `undefined` (a record written
|
|
120
|
+
* before the update keys became client-held); a present-but-malformed one
|
|
121
|
+
* throws.
|
|
122
|
+
*
|
|
123
|
+
* @param value {unknown} the record's `webvh` member
|
|
124
|
+
* @returns {ClientWebvhUpdateKeys | undefined}
|
|
125
|
+
*/
|
|
126
|
+
export function parseClientRecordWebvhKeys(value) {
|
|
127
|
+
if (value === undefined) {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
if (value === null || typeof value !== 'object') {
|
|
131
|
+
throw new Error('Client-key record has malformed did:webvh update keys.');
|
|
132
|
+
}
|
|
133
|
+
const { updateSeed, stagedSeed, pendingStagedSeed } = value;
|
|
134
|
+
return {
|
|
135
|
+
updateSeed: decodeSecret({
|
|
136
|
+
value: updateSeed,
|
|
137
|
+
name: 'did:webvh update seed'
|
|
138
|
+
}),
|
|
139
|
+
stagedSeed: decodeSecret({
|
|
140
|
+
value: stagedSeed,
|
|
141
|
+
name: 'did:webvh staged seed'
|
|
142
|
+
}),
|
|
143
|
+
...(pendingStagedSeed !== undefined
|
|
144
|
+
? {
|
|
145
|
+
pendingStagedSeed: decodeSecret({
|
|
146
|
+
value: pendingStagedSeed,
|
|
147
|
+
name: 'did:webvh pending staged seed'
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
: {})
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Encodes a client-key record's contents for storage: base64url byte fields,
|
|
155
|
+
* optional members omitted rather than written as null.
|
|
156
|
+
*
|
|
157
|
+
* @param options {object}
|
|
158
|
+
* @param options.clientSeed {Uint8Array} this client's 32-byte seed
|
|
159
|
+
* @param [options.puk] {Puk} the cached per-user key
|
|
160
|
+
* @param [options.webvhUpdateKeys] {ClientWebvhUpdateKeys} this client's
|
|
161
|
+
* did:webvh update-key seeds
|
|
162
|
+
* @param [options.controller] {string} the account controller this key set
|
|
163
|
+
* was bound for -- on an enrolled (non-first) client it differs from the
|
|
164
|
+
* client's own did:key
|
|
165
|
+
* @param [options.pointerDid] {string} the account's did:webvh
|
|
166
|
+
* @param [options.createdAt] {string} when the record was written; defaults
|
|
167
|
+
* to now
|
|
168
|
+
* @returns {ClientKeyRecordJson}
|
|
169
|
+
*/
|
|
170
|
+
export function encodeClientKeyRecord({ clientSeed, puk, webvhUpdateKeys, controller, pointerDid, createdAt = new Date().toISOString() }) {
|
|
171
|
+
if (clientSeed.length !== SECRET_BYTES) {
|
|
172
|
+
throw new Error(`Client-key record client seed is not ${SECRET_BYTES} bytes.`);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
clientSeed: base64urlnopad.encode(clientSeed),
|
|
176
|
+
...(puk
|
|
177
|
+
? {
|
|
178
|
+
puk: {
|
|
179
|
+
id: puk.id,
|
|
180
|
+
secret: base64urlnopad.encode(puk.secret),
|
|
181
|
+
...(puk.signingSeed
|
|
182
|
+
? { signingSeed: base64urlnopad.encode(puk.signingSeed) }
|
|
183
|
+
: {})
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
: {}),
|
|
187
|
+
...(webvhUpdateKeys
|
|
188
|
+
? {
|
|
189
|
+
webvh: {
|
|
190
|
+
updateSeed: base64urlnopad.encode(webvhUpdateKeys.updateSeed),
|
|
191
|
+
stagedSeed: base64urlnopad.encode(webvhUpdateKeys.stagedSeed),
|
|
192
|
+
...(webvhUpdateKeys.pendingStagedSeed
|
|
193
|
+
? {
|
|
194
|
+
pendingStagedSeed: base64urlnopad.encode(webvhUpdateKeys.pendingStagedSeed)
|
|
195
|
+
}
|
|
196
|
+
: {})
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
: {}),
|
|
200
|
+
...(controller ? { controller } : {}),
|
|
201
|
+
...(pointerDid ? { pointerDid } : {}),
|
|
202
|
+
createdAt
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Decodes and validates a stored client-key record's contents. Throws on any
|
|
207
|
+
* malformed member -- see the module doc for why nothing here is tolerated
|
|
208
|
+
* into a degraded record.
|
|
209
|
+
*
|
|
210
|
+
* @param options {object}
|
|
211
|
+
* @param options.contents {unknown} the stored JSON contents (an app that
|
|
212
|
+
* stores a string parses it first)
|
|
213
|
+
* @returns {ClientKeyRecord}
|
|
214
|
+
*/
|
|
215
|
+
export function decodeClientKeyRecord({ contents }) {
|
|
216
|
+
if (contents === null || typeof contents !== 'object') {
|
|
217
|
+
throw new Error('Malformed client-key record.');
|
|
218
|
+
}
|
|
219
|
+
const { clientSeed, puk, webvh, controller, pointerDid } = contents;
|
|
220
|
+
const seed = decodeSecret({ value: clientSeed, name: 'client seed' });
|
|
221
|
+
if (controller !== undefined &&
|
|
222
|
+
(typeof controller !== 'string' || !controller)) {
|
|
223
|
+
throw new Error('Client-key record has a malformed controller.');
|
|
224
|
+
}
|
|
225
|
+
if (pointerDid !== undefined &&
|
|
226
|
+
(typeof pointerDid !== 'string' || !pointerDid)) {
|
|
227
|
+
throw new Error('Client-key record has a malformed account pointer DID.');
|
|
228
|
+
}
|
|
229
|
+
const parsedPuk = parseClientRecordPuk(puk);
|
|
230
|
+
const webvhUpdateKeys = parseClientRecordWebvhKeys(webvh);
|
|
231
|
+
return {
|
|
232
|
+
clientSeed: seed,
|
|
233
|
+
...(parsedPuk ? { puk: parsedPuk } : {}),
|
|
234
|
+
...(webvhUpdateKeys ? { webvhUpdateKeys } : {}),
|
|
235
|
+
...(controller ? { controller } : {}),
|
|
236
|
+
...(pointerDid ? { pointerDid } : {})
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Narrows a decoded record to a complete enrolled-client key set, throwing
|
|
241
|
+
* when any member an enrolled client needs is absent. For an app whose stored
|
|
242
|
+
* records are only ever written by the enrollment ceremony, this turns "the
|
|
243
|
+
* codec tolerates older records" into a single checked boundary.
|
|
244
|
+
*
|
|
245
|
+
* @param options {object}
|
|
246
|
+
* @param options.record {ClientKeyRecord}
|
|
247
|
+
* @returns {EnrolledClientKeyRecord}
|
|
248
|
+
*/
|
|
249
|
+
export function assertEnrolledClientKeyRecord({ record }) {
|
|
250
|
+
const { puk, webvhUpdateKeys, controller, pointerDid } = record;
|
|
251
|
+
if (!puk) {
|
|
252
|
+
throw new Error('Client-key record carries no per-user key.');
|
|
253
|
+
}
|
|
254
|
+
if (!webvhUpdateKeys) {
|
|
255
|
+
throw new Error('Client-key record carries no did:webvh update keys.');
|
|
256
|
+
}
|
|
257
|
+
if (!controller) {
|
|
258
|
+
throw new Error('Client-key record carries no account controller.');
|
|
259
|
+
}
|
|
260
|
+
if (!pointerDid) {
|
|
261
|
+
throw new Error('Client-key record carries no account pointer DID.');
|
|
262
|
+
}
|
|
263
|
+
return { ...record, puk, webvhUpdateKeys, controller, pointerDid };
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=clientKeyRecord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* - `mintPuk` / `pukVaultKeys` -- minting the account's PUK and rebuilding the
|
|
10
10
|
* vault key-agreement key + resolver from stored material.
|
|
11
|
+
* - `encodeClientKeyRecord` / `decodeClientKeyRecord` -- the contents codec and
|
|
12
|
+
* strict validation of the local client-key record each client keeps its own
|
|
13
|
+
* key material in (storage and wrapping stay app-side).
|
|
11
14
|
* - `ensurePukRoster` / `addPukRosterRecipient` / `readPukRoster` /
|
|
12
15
|
* `pukRosterRecipientResolver` -- the `key-map/puk.json` roster over the
|
|
13
16
|
* was-client descriptor-store seam, with the three client-side guards a
|
|
@@ -34,6 +37,8 @@
|
|
|
34
37
|
*/
|
|
35
38
|
export { mintPuk, pukVaultKeys } from './puk.js';
|
|
36
39
|
export type { Puk } from './puk.js';
|
|
40
|
+
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordPuk, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
41
|
+
export type { ClientKeyRecord, ClientKeyRecordJson, EnrolledClientKeyRecord } from './clientKeyRecord.js';
|
|
37
42
|
export { addPukRosterRecipient, convergePukRosterToDocument, ensurePukRoster, PukRosterContinuityError, PukRosterIntegrityError, PukRosterUnwrapError, pukRosterRecipientResolver, readPukRoster, rosterRecipientKid, rotatePukRoster } from './pukRoster.js';
|
|
38
43
|
export { cascadeCollectionsToPuk, pukAsRecipient, rotateCollectionEpochsToPuk, unwrapPukGenerations } from './pukCascade.js';
|
|
39
44
|
export type { CollectionPukRotationOutcome, PukCascadeResult } from './pukCascade.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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAChD,YAAY,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAEnC,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,EACb,kBAAkB,EAClB,eAAe,EAChB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,4BAA4B,EAC5B,gBAAgB,EACjB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAE3D,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
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
*
|
|
9
9
|
* - `mintPuk` / `pukVaultKeys` -- minting the account's PUK and rebuilding the
|
|
10
10
|
* vault key-agreement key + resolver from stored material.
|
|
11
|
+
* - `encodeClientKeyRecord` / `decodeClientKeyRecord` -- the contents codec and
|
|
12
|
+
* strict validation of the local client-key record each client keeps its own
|
|
13
|
+
* key material in (storage and wrapping stay app-side).
|
|
11
14
|
* - `ensurePukRoster` / `addPukRosterRecipient` / `readPukRoster` /
|
|
12
15
|
* `pukRosterRecipientResolver` -- the `key-map/puk.json` roster over the
|
|
13
16
|
* was-client descriptor-store seam, with the three client-side guards a
|
|
@@ -33,6 +36,7 @@
|
|
|
33
36
|
* names (also the completion sweep's driver).
|
|
34
37
|
*/
|
|
35
38
|
export { mintPuk, pukVaultKeys } from './puk.js';
|
|
39
|
+
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordPuk, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
36
40
|
export { addPukRosterRecipient, convergePukRosterToDocument, ensurePukRoster, PukRosterContinuityError, PukRosterIntegrityError, PukRosterUnwrapError, pukRosterRecipientResolver, readPukRoster, rosterRecipientKid, rotatePukRoster } from './pukRoster.js';
|
|
37
41
|
export { cascadeCollectionsToPuk, pukAsRecipient, rotateCollectionEpochsToPuk, unwrapPukGenerations } from './pukCascade.js';
|
|
38
42
|
export { pukRosterDescriptorStore } from './rosterStore.js';
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAGhD,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,EACb,kBAAkB,EAClB,eAAe,EAChB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,iBAAiB,CAAA;AAUxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAE3D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/request/index.d.ts
CHANGED
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
* `interactionUrl` resolves VCALM `interaction:` URLs.
|
|
20
20
|
* - `processRequest` is the pure request-to-response pipeline, with the
|
|
21
21
|
* app-side side effects injected.
|
|
22
|
+
* - `classifyWalletInput` / `handleWalletInput` are the ordered
|
|
23
|
+
* discrimination every "scan or paste something" entry point runs, with the
|
|
24
|
+
* per-grammar handlers injected.
|
|
22
25
|
*
|
|
23
26
|
* The signing / document-loader dependency graph lives entirely behind this
|
|
24
27
|
* subpath; `@interop/wallet-core`'s plaintext consumers never pull it in.
|
|
@@ -32,4 +35,5 @@ export * from './composeVp.js';
|
|
|
32
35
|
export * from './exchangeClient.js';
|
|
33
36
|
export * from './interactionUrl.js';
|
|
34
37
|
export * from './processRequest.js';
|
|
38
|
+
export * from './walletInput.js';
|
|
35
39
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA"}
|
package/dist/request/index.js
CHANGED
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
* `interactionUrl` resolves VCALM `interaction:` URLs.
|
|
20
20
|
* - `processRequest` is the pure request-to-response pipeline, with the
|
|
21
21
|
* app-side side effects injected.
|
|
22
|
+
* - `classifyWalletInput` / `handleWalletInput` are the ordered
|
|
23
|
+
* discrimination every "scan or paste something" entry point runs, with the
|
|
24
|
+
* per-grammar handlers injected.
|
|
22
25
|
*
|
|
23
26
|
* The signing / document-loader dependency graph lives entirely behind this
|
|
24
27
|
* subpath; `@interop/wallet-core`'s plaintext consumers never pull it in.
|
|
@@ -32,4 +35,5 @@ export * from './composeVp.js';
|
|
|
32
35
|
export * from './exchangeClient.js';
|
|
33
36
|
export * from './interactionUrl.js';
|
|
34
37
|
export * from './processRequest.js';
|
|
38
|
+
export * from './walletInput.js';
|
|
35
39
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/request/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA;AAC7B,cAAc,wBAAwB,CAAA;AACtC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { WalletApiMessage } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* What a piece of wallet input turned out to be. Every variant carries the
|
|
4
|
+
* trimmed `text` it was classified from, plus whatever the classification
|
|
5
|
+
* already parsed (a classifier that recognized a grammar has usually parsed
|
|
6
|
+
* enough of it that re-parsing in the handler would be waste and drift).
|
|
7
|
+
*/
|
|
8
|
+
export type WalletInput = {
|
|
9
|
+
kind: 'was-link';
|
|
10
|
+
text: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'connect-code';
|
|
13
|
+
text: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'legacy-request';
|
|
16
|
+
text: string;
|
|
17
|
+
params: Record<string, string>;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'interaction-url';
|
|
20
|
+
text: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'deep-link';
|
|
23
|
+
text: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'wallet-api-message';
|
|
26
|
+
text: string;
|
|
27
|
+
message: WalletApiMessage;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'credentials';
|
|
30
|
+
text: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Classifies one piece of wallet input. See the module doc for the order and
|
|
34
|
+
* why each branch sits where it does.
|
|
35
|
+
*
|
|
36
|
+
* @param text {string} the scanned, pasted, or opened text
|
|
37
|
+
* @param [options] {object}
|
|
38
|
+
* @param [options.deepLinkSchemes] {string[]} the link prefixes this app has
|
|
39
|
+
* registered (custom protocols and universal app links). Empty, the
|
|
40
|
+
* deep-link and legacy-request branches never match -- a wallet with no
|
|
41
|
+
* registered links has nothing to route them to
|
|
42
|
+
* @returns {WalletInput}
|
|
43
|
+
*/
|
|
44
|
+
export declare function classifyWalletInput(text: string, { deepLinkSchemes }?: {
|
|
45
|
+
deepLinkSchemes?: string[];
|
|
46
|
+
}): WalletInput;
|
|
47
|
+
/**
|
|
48
|
+
* The handlers a caller injects, one per classified kind. Every handler is
|
|
49
|
+
* optional: an input whose kind has no handler throws, which is what keeps a
|
|
50
|
+
* wallet that does not implement a grammar from silently doing the wrong thing
|
|
51
|
+
* with it.
|
|
52
|
+
*/
|
|
53
|
+
export interface WalletInputHandlers<T> {
|
|
54
|
+
wasLink?: (input: {
|
|
55
|
+
text: string;
|
|
56
|
+
}) => T | Promise<T>;
|
|
57
|
+
connectCode?: (input: {
|
|
58
|
+
text: string;
|
|
59
|
+
}) => T | Promise<T>;
|
|
60
|
+
legacyRequest?: (input: {
|
|
61
|
+
text: string;
|
|
62
|
+
params: Record<string, string>;
|
|
63
|
+
}) => T | Promise<T>;
|
|
64
|
+
interactionUrl?: (input: {
|
|
65
|
+
text: string;
|
|
66
|
+
}) => T | Promise<T>;
|
|
67
|
+
deepLink?: (input: {
|
|
68
|
+
text: string;
|
|
69
|
+
}) => T | Promise<T>;
|
|
70
|
+
walletApiMessage?: (input: {
|
|
71
|
+
text: string;
|
|
72
|
+
message: WalletApiMessage;
|
|
73
|
+
}) => T | Promise<T>;
|
|
74
|
+
credentials?: (input: {
|
|
75
|
+
text: string;
|
|
76
|
+
}) => T | Promise<T>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Classifies input and dispatches it to the matching handler.
|
|
80
|
+
*
|
|
81
|
+
* @param options {object}
|
|
82
|
+
* @param options.text {string} the scanned, pasted, or opened text
|
|
83
|
+
* @param [options.deepLinkSchemes] {string[]} this app's registered link
|
|
84
|
+
* prefixes
|
|
85
|
+
* @param options.handlers {WalletInputHandlers} the injected handlers
|
|
86
|
+
* @returns {Promise<*>} whatever the matching handler resolves to
|
|
87
|
+
*/
|
|
88
|
+
export declare function handleWalletInput<T>({ text, deepLinkSchemes, handlers }: {
|
|
89
|
+
text: string;
|
|
90
|
+
deepLinkSchemes?: string[];
|
|
91
|
+
handlers: WalletInputHandlers<T>;
|
|
92
|
+
}): Promise<T>;
|
|
93
|
+
//# sourceMappingURL=walletInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walletInput.d.ts","sourceRoot":"","sources":["../../src/request/walletInput.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AASlD;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAsCzC;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,EAAE,eAAoB,EAAE,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC5D,WAAW,CA2Cb;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACrD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACzD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACtB,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAC/B,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACpB,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAC5D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACtD,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QACzB,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,gBAAgB,CAAA;KAC1B,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACpB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAC1D;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,EACzC,IAAI,EACJ,eAAe,EACf,QAAQ,EACT,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAA;CACjC,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBb"}
|