@interop/wallet-core 0.5.0 → 0.7.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.
Files changed (113) hide show
  1. package/dist/enrollment/enrollment.d.ts +144 -0
  2. package/dist/enrollment/enrollment.d.ts.map +1 -0
  3. package/dist/enrollment/enrollment.js +296 -0
  4. package/dist/enrollment/enrollment.js.map +1 -0
  5. package/dist/enrollment/index.d.ts +20 -0
  6. package/dist/enrollment/index.d.ts.map +1 -0
  7. package/dist/enrollment/index.js +19 -0
  8. package/dist/enrollment/index.js.map +1 -0
  9. package/dist/identity/index.d.ts +0 -5
  10. package/dist/identity/index.d.ts.map +1 -1
  11. package/dist/identity/index.js +0 -4
  12. package/dist/identity/index.js.map +1 -1
  13. package/dist/index.d.ts +16 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +16 -3
  16. package/dist/index.js.map +1 -1
  17. package/dist/keyring/fetch.d.ts +22 -0
  18. package/dist/keyring/fetch.d.ts.map +1 -0
  19. package/dist/keyring/fetch.js +35 -0
  20. package/dist/keyring/fetch.js.map +1 -0
  21. package/dist/keyring/index.d.ts +30 -0
  22. package/dist/keyring/index.d.ts.map +1 -0
  23. package/dist/keyring/index.js +28 -0
  24. package/dist/keyring/index.js.map +1 -0
  25. package/dist/keyring/kdf.d.ts +102 -0
  26. package/dist/keyring/kdf.d.ts.map +1 -0
  27. package/dist/keyring/kdf.js +148 -0
  28. package/dist/keyring/kdf.js.map +1 -0
  29. package/dist/keyring/record.d.ts +98 -0
  30. package/dist/keyring/record.d.ts.map +1 -0
  31. package/dist/keyring/record.js +119 -0
  32. package/dist/keyring/record.js.map +1 -0
  33. package/dist/keyring/unlockSpace.d.ts +101 -0
  34. package/dist/keyring/unlockSpace.d.ts.map +1 -0
  35. package/dist/keyring/unlockSpace.js +226 -0
  36. package/dist/keyring/unlockSpace.js.map +1 -0
  37. package/dist/keys/index.d.ts +24 -0
  38. package/dist/keys/index.d.ts.map +1 -0
  39. package/dist/keys/index.js +22 -0
  40. package/dist/keys/index.js.map +1 -0
  41. package/dist/keys/puk.d.ts +42 -0
  42. package/dist/keys/puk.d.ts.map +1 -0
  43. package/dist/keys/puk.js +56 -0
  44. package/dist/keys/puk.js.map +1 -0
  45. package/dist/keys/pukRoster.d.ts +210 -0
  46. package/dist/keys/pukRoster.d.ts.map +1 -0
  47. package/dist/keys/pukRoster.js +263 -0
  48. package/dist/keys/pukRoster.js.map +1 -0
  49. package/dist/keys/rosterStore.d.ts +18 -0
  50. package/dist/keys/rosterStore.d.ts.map +1 -0
  51. package/dist/keys/rosterStore.js +38 -0
  52. package/dist/keys/rosterStore.js.map +1 -0
  53. package/dist/markers/acquire.d.ts +107 -0
  54. package/dist/markers/acquire.d.ts.map +1 -0
  55. package/dist/markers/acquire.js +83 -0
  56. package/dist/markers/acquire.js.map +1 -0
  57. package/dist/markers/cipher.d.ts +56 -0
  58. package/dist/markers/cipher.d.ts.map +1 -0
  59. package/dist/markers/cipher.js +73 -0
  60. package/dist/markers/cipher.js.map +1 -0
  61. package/dist/markers/index.d.ts +30 -0
  62. package/dist/markers/index.d.ts.map +1 -0
  63. package/dist/markers/index.js +29 -0
  64. package/dist/markers/index.js.map +1 -0
  65. package/dist/markers/refresh.d.ts +60 -0
  66. package/dist/markers/refresh.d.ts.map +1 -0
  67. package/dist/markers/refresh.js +67 -0
  68. package/dist/markers/refresh.js.map +1 -0
  69. package/dist/recovery/index.d.ts +31 -0
  70. package/dist/recovery/index.d.ts.map +1 -0
  71. package/dist/recovery/index.js +28 -0
  72. package/dist/recovery/index.js.map +1 -0
  73. package/dist/recovery/recoveryCode.d.ts +105 -0
  74. package/dist/recovery/recoveryCode.d.ts.map +1 -0
  75. package/dist/recovery/recoveryCode.js +155 -0
  76. package/dist/recovery/recoveryCode.js.map +1 -0
  77. package/dist/recovery/recoveryRecord.d.ts +75 -0
  78. package/dist/recovery/recoveryRecord.d.ts.map +1 -0
  79. package/dist/recovery/recoveryRecord.js +89 -0
  80. package/dist/recovery/recoveryRecord.js.map +1 -0
  81. package/dist/recovery/recoveryWebvh.d.ts +126 -0
  82. package/dist/recovery/recoveryWebvh.d.ts.map +1 -0
  83. package/dist/recovery/recoveryWebvh.js +379 -0
  84. package/dist/recovery/recoveryWebvh.js.map +1 -0
  85. package/dist/space/collections.d.ts +57 -0
  86. package/dist/space/collections.d.ts.map +1 -1
  87. package/dist/space/collections.js +48 -0
  88. package/dist/space/collections.js.map +1 -1
  89. package/dist/space/index.d.ts +4 -0
  90. package/dist/space/index.d.ts.map +1 -1
  91. package/dist/space/index.js +4 -0
  92. package/dist/space/index.js.map +1 -1
  93. package/dist/webvh/didWeb.d.ts +41 -0
  94. package/dist/webvh/didWeb.d.ts.map +1 -0
  95. package/dist/webvh/didWeb.js +24 -0
  96. package/dist/webvh/didWeb.js.map +1 -0
  97. package/dist/webvh/didWebvh.d.ts +330 -0
  98. package/dist/webvh/didWebvh.d.ts.map +1 -0
  99. package/dist/webvh/didWebvh.js +775 -0
  100. package/dist/webvh/didWebvh.js.map +1 -0
  101. package/dist/webvh/index.d.ts +27 -0
  102. package/dist/webvh/index.d.ts.map +1 -0
  103. package/dist/webvh/index.js +24 -0
  104. package/dist/webvh/index.js.map +1 -0
  105. package/dist/webvh/zcap.d.ts +104 -0
  106. package/dist/webvh/zcap.d.ts.map +1 -0
  107. package/dist/webvh/zcap.js +117 -0
  108. package/dist/webvh/zcap.js.map +1 -0
  109. package/package.json +42 -4
  110. package/dist/identity/collectionKeys.d.ts +0 -36
  111. package/dist/identity/collectionKeys.d.ts.map +0 -1
  112. package/dist/identity/collectionKeys.js +0 -92
  113. package/dist/identity/collectionKeys.js.map +0 -1
@@ -0,0 +1,144 @@
1
+ import type { IKeyAgreementKey } from '@interop/data-integrity-core';
2
+ import type { MarkerStore } from '@interop/was-client/edv';
3
+ import type { ClientWebvhUpdateKeys, WebvhEnrollmentKeys, WebvhIdStore } from '../webvh/didWebvh.js';
4
+ import type { Puk } from '../keys/puk.js';
5
+ import type { AccountPointer } from '../keyring/record.js';
6
+ /**
7
+ * The public halves a connect code carries -- the same four multibases
8
+ * `enrollWebvhClient` publishes into the document, minted by the enrollee and
9
+ * verified point-to-point by the person running the ceremony.
10
+ */
11
+ export type EnrollmentRequest = WebvhEnrollmentKeys;
12
+ /**
13
+ * Thrown by the enrollee's completion step while the enrolling side has not
14
+ * (yet) published the add entry -- the "not approved yet" state, retried by
15
+ * completing again once the other client finishes.
16
+ */
17
+ export declare class EnrollmentPendingError extends Error {
18
+ constructor(message?: string);
19
+ }
20
+ /**
21
+ * Encodes an enrollment request as a connect code.
22
+ *
23
+ * @param options {object}
24
+ * @param options.request {EnrollmentRequest}
25
+ * @returns {string}
26
+ */
27
+ export declare function encodeEnrollmentRequest({ request }: {
28
+ request: EnrollmentRequest;
29
+ }): string;
30
+ /**
31
+ * Parses and validates a connect code: the prefix, the payload version, and
32
+ * the shape of each key (Ed25519 multibase for the signing and update keys,
33
+ * X25519 for the key-agreement key). Throws on anything malformed -- a code
34
+ * is typed or scanned, so a clear refusal beats a half-parsed ceremony.
35
+ *
36
+ * @param options {object}
37
+ * @param options.code {string} the pasted/scanned connect code
38
+ * @returns {EnrollmentRequest}
39
+ */
40
+ export declare function parseEnrollmentRequest({ code }: {
41
+ code: string;
42
+ }): EnrollmentRequest;
43
+ /**
44
+ * The did:key a connect code's signing key derives -- shown on BOTH screens
45
+ * so the person running the ceremony can compare them before approving (the
46
+ * point-to-point verification the wrap and the document VM then inherit).
47
+ *
48
+ * @param options {object}
49
+ * @param options.request {EnrollmentRequest}
50
+ * @returns {string}
51
+ */
52
+ export declare function enrollmentClientDid({ request }: {
53
+ request: EnrollmentRequest;
54
+ }): string;
55
+ /**
56
+ * The kid of the enrollee's roster entry: its key-agreement key's id exactly
57
+ * as `agentsFromSeed` will derive it at the enrollee's own logins
58
+ * (`did:key:<ed-multibase>#<x-multibase>`), so the wrap minted here is the
59
+ * one its first roster read looks for.
60
+ *
61
+ * @param options {object}
62
+ * @param options.request {EnrollmentRequest}
63
+ * @returns {string}
64
+ */
65
+ export declare function enrollmentRecipientKid({ request }: {
66
+ request: EnrollmentRequest;
67
+ }): string;
68
+ /**
69
+ * ENROLLEE, step one: mints the new client's whole key set locally and
70
+ * returns it alongside the connect code to display. The caller holds the
71
+ * seeds in memory until the completion step persists them -- nothing is
72
+ * durable before the ceremony succeeds, so abandoning it leaks at most an
73
+ * orphan wrap on the enrolling side.
74
+ *
75
+ * @returns {Promise<object>} the in-memory key set, the code, and the
76
+ * client did:key to display beside it for comparison
77
+ */
78
+ export declare function mintEnrollmentRequest(): Promise<{
79
+ clientSeed: Uint8Array;
80
+ webvhUpdateKeys: ClientWebvhUpdateKeys;
81
+ code: string;
82
+ clientDid: string;
83
+ }>;
84
+ /**
85
+ * ENROLLING CLIENT: the whole approval, in the push order -- the PUK wrapped
86
+ * into the roster first (escrow: every epoch, so the new client reads
87
+ * pre-enrollment history), then the two log entries. Quorum-of-one: this
88
+ * client's own update key signs both entries. Idempotent at every stage, so
89
+ * re-approving the same code after any tear converges.
90
+ *
91
+ * @param options {object}
92
+ * @param options.request {EnrollmentRequest} the parsed connect code
93
+ * @param options.clientWebvhKeys {ClientWebvhUpdateKeys} the approving
94
+ * client's own did:webvh update-key seeds
95
+ * @param options.clientKeyAgreementKey {IKeyAgreementKey} the approving
96
+ * client's own (identity) key-agreement key, unwrapping each epoch for
97
+ * re-wrapping
98
+ * @param options.pukRosterStore {MarkerStore} the account's
99
+ * `key-map/puk.json` marker store
100
+ * @param options.idStore {WebvhIdStore} the account's `id` collection
101
+ * @returns {Promise<{ did: string }>} the account's did:webvh
102
+ */
103
+ export declare function approveEnrollment({ request, clientWebvhKeys, clientKeyAgreementKey, pukRosterStore, idStore }: {
104
+ request: EnrollmentRequest;
105
+ clientWebvhKeys: ClientWebvhUpdateKeys;
106
+ clientKeyAgreementKey: IKeyAgreementKey;
107
+ pukRosterStore: MarkerStore;
108
+ idStore: WebvhIdStore;
109
+ }): Promise<{
110
+ did: string;
111
+ }>;
112
+ /**
113
+ * ENROLLEE, step two (after the other client approves): verifies the
114
+ * enrollment from the world-readable log and performs this client's first
115
+ * roster read -- signed with its just-published `<did:webvh>#<multibase>`
116
+ * key -- to obtain the PUK.
117
+ *
118
+ * The portable core of the completion step: the caller supplies the account
119
+ * pointer (from its own keyring lookup) and persists what comes back -- the
120
+ * PUK, the roster epoch to pin, and the key set itself -- under its own unlock
121
+ * layer. After that, an ordinary unlock finds an enrolled client.
122
+ *
123
+ * Throws `EnrollmentPendingError` while the add entry is not published yet
124
+ * (complete again once the other client finishes); any integrity failure
125
+ * (a log that resolves to a different DID than the account pointer names, a
126
+ * missing roster wrap) throws its own error.
127
+ *
128
+ * @param options {object}
129
+ * @param options.clientSeed {Uint8Array} from `mintEnrollmentRequest`
130
+ * @param options.webvhUpdateKeys {ClientWebvhUpdateKeys} from
131
+ * `mintEnrollmentRequest`
132
+ * @param options.pointer {AccountPointer} the account pointer the enrollee's
133
+ * keyring lookup recovered
134
+ * @returns {Promise<{ puk: Puk, latestEpochId: string }>}
135
+ */
136
+ export declare function completeEnrollmentCore({ clientSeed, webvhUpdateKeys, pointer }: {
137
+ clientSeed: Uint8Array;
138
+ webvhUpdateKeys: ClientWebvhUpdateKeys;
139
+ pointer: AccountPointer;
140
+ }): Promise<{
141
+ puk: Puk;
142
+ latestEpochId: string;
143
+ }>;
144
+ //# sourceMappingURL=enrollment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrollment.d.ts","sourceRoot":"","sources":["../../src/enrollment/enrollment.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAS1D,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACb,MAAM,sBAAsB,CAAA;AAS7B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAa1D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,CAAA;AAEnD;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBAE7C,OAAO,SAC+C;CAKzD;AASD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACR,EAAE;IACD,OAAO,EAAE,iBAAiB,CAAA;CAC3B,GAAG,MAAM,CAKT;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAA;CACb,GAAG,iBAAiB,CAwDpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACR,EAAE;IACD,OAAO,EAAE,iBAAiB,CAAA;CAC3B,GAAG,MAAM,CAET;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,OAAO,EACR,EAAE;IACD,OAAO,EAAE,iBAAiB,CAAA;CAC3B,GAAG,MAAM,CAET;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC;IACrD,UAAU,EAAE,UAAU,CAAA;IACtB,eAAe,EAAE,qBAAqB,CAAA;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;CAClB,CAAC,CA2BD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,OAAO,EACR,EAAE;IACD,OAAO,EAAE,iBAAiB,CAAA;IAC1B,eAAe,EAAE,qBAAqB,CAAA;IACtC,qBAAqB,EAAE,gBAAgB,CAAA;IACvC,cAAc,EAAE,WAAW,CAAA;IAC3B,OAAO,EAAE,YAAY,CAAA;CACtB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAiB3B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,UAAU,EACV,eAAe,EACf,OAAO,EACR,EAAE;IACD,UAAU,EAAE,UAAU,CAAA;IACtB,eAAe,EAAE,qBAAqB,CAAA;IACtC,OAAO,EAAE,cAAc,CAAA;CACxB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CA2E/C"}
@@ -0,0 +1,296 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The client enrollment ceremony: connecting a second wallet client (a fresh
6
+ * browser profile, another app install) to an existing account without any
7
+ * secret ever leaving either side. The new client mints its whole key set
8
+ * locally -- client seed, did:webvh update-key seeds -- and only PUBLIC halves
9
+ * travel, as a compact "connect code" carried point-to-point (pasted between
10
+ * two browsers in the room today; the same payload renders as a QR for a
11
+ * camera-holding wallet). Nothing travels back over the channel: the account
12
+ * pointer comes out of the keyring (the enrollee holds the unlock secret), and
13
+ * the PUK comes back through the wrap-set roster.
14
+ *
15
+ * Push, not pull, in the recovery-anchor order (decryption material before
16
+ * authorization): the enrolling client wraps the PUK to the new client's
17
+ * key-agreement key in `key-map/puk.json` FIRST, then writes the two
18
+ * did:webvh log entries (commit, then add-VMs-and-update-key). No
19
+ * authorized-but-blind window exists at any point, and both tear points
20
+ * resume by re-running the ceremony with the same code -- a tear after the
21
+ * roster write leaves an orphan wrap (invisible to authorization), a tear
22
+ * between the log entries is detected from the published commitments.
23
+ *
24
+ * The new client's first roster read happens post-enrollment, signed with its
25
+ * `<did:webvh>#<multibase>` key -- the server authorizes it under the
26
+ * current-key-set rule the moment the add entry publishes. Persisting the key
27
+ * set under the app's own unlock layer is the caller's job: this module hands
28
+ * back the PUK and the roster epoch to pin, and stops there.
29
+ */
30
+ import { readLogFromString, resolveDIDFromLog } from '@interop/did-method-webvh';
31
+ import { base64urlnopad } from '@scure/base';
32
+ import { agentsFromSeed } from '../identity/agents.js';
33
+ import { DID_LOG_RESOURCE, ID_COLLECTION } from '../space/collections.js';
34
+ import { enrollWebvhClient, mintClientWebvhUpdateKeys, updateKeyMultibase } from '../webvh/didWebvh.js';
35
+ import { clientSigningKeyMultibase, isWebvhDid, webvhZcapClient } from '../webvh/zcap.js';
36
+ import { addPukRosterRecipient } from '../keys/pukRoster.js';
37
+ import { readPukRoster } from '../keys/pukRoster.js';
38
+ import { pukRosterMarkerStore } from '../keys/rosterStore.js';
39
+ /**
40
+ * The connect-code prefix; the payload after it is base64url(JSON) of an
41
+ * `EnrollmentRequest` plus a `v` version stamp.
42
+ */
43
+ const CONNECT_CODE_PREFIX = 'freewallet-connect:';
44
+ /**
45
+ * The connect-code payload version this build mints and accepts.
46
+ */
47
+ const CONNECT_CODE_VERSION = 1;
48
+ /**
49
+ * Thrown by the enrollee's completion step while the enrolling side has not
50
+ * (yet) published the add entry -- the "not approved yet" state, retried by
51
+ * completing again once the other client finishes.
52
+ */
53
+ export class EnrollmentPendingError extends Error {
54
+ constructor(message = 'This browser is not enrolled yet; approve the connect code ' +
55
+ 'from an already-connected browser, then try again.') {
56
+ super(message);
57
+ this.name = 'EnrollmentPendingError';
58
+ }
59
+ }
60
+ /**
61
+ * The multicodec multibase prefixes of the two key types a connect code
62
+ * carries: Ed25519 (`z6Mk`) and X25519 (`z6LS`) public keys.
63
+ */
64
+ const ED25519_MULTIBASE_PREFIX = 'z6Mk';
65
+ const X25519_MULTIBASE_PREFIX = 'z6LS';
66
+ /**
67
+ * Encodes an enrollment request as a connect code.
68
+ *
69
+ * @param options {object}
70
+ * @param options.request {EnrollmentRequest}
71
+ * @returns {string}
72
+ */
73
+ export function encodeEnrollmentRequest({ request }) {
74
+ const payload = JSON.stringify({ v: CONNECT_CODE_VERSION, ...request });
75
+ return `${CONNECT_CODE_PREFIX}${base64urlnopad.encode(new TextEncoder().encode(payload))}`;
76
+ }
77
+ /**
78
+ * Parses and validates a connect code: the prefix, the payload version, and
79
+ * the shape of each key (Ed25519 multibase for the signing and update keys,
80
+ * X25519 for the key-agreement key). Throws on anything malformed -- a code
81
+ * is typed or scanned, so a clear refusal beats a half-parsed ceremony.
82
+ *
83
+ * @param options {object}
84
+ * @param options.code {string} the pasted/scanned connect code
85
+ * @returns {EnrollmentRequest}
86
+ */
87
+ export function parseEnrollmentRequest({ code }) {
88
+ const trimmed = code.trim();
89
+ if (!trimmed.startsWith(CONNECT_CODE_PREFIX)) {
90
+ throw new Error('Not a wallet connect code.');
91
+ }
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(new TextDecoder().decode(base64urlnopad.decode(trimmed.slice(CONNECT_CODE_PREFIX.length))));
95
+ }
96
+ catch (err) {
97
+ throw new Error('The connect code payload is malformed.', { cause: err });
98
+ }
99
+ if (parsed === null || typeof parsed !== 'object') {
100
+ throw new Error('The connect code payload is malformed.');
101
+ }
102
+ const { v, signingKeyMultibase, keyAgreementKeyMultibase, updateKeyMultibase: updateKey, stagedUpdateKeyMultibase } = parsed;
103
+ if (v !== CONNECT_CODE_VERSION) {
104
+ throw new Error(`Unsupported connect code version "${String(v)}".`);
105
+ }
106
+ const requireKey = (value, prefix, name) => {
107
+ if (typeof value !== 'string' || !value.startsWith(prefix)) {
108
+ throw new Error(`The connect code carries a malformed ${name}.`);
109
+ }
110
+ return value;
111
+ };
112
+ return {
113
+ signingKeyMultibase: requireKey(signingKeyMultibase, ED25519_MULTIBASE_PREFIX, 'signing key'),
114
+ keyAgreementKeyMultibase: requireKey(keyAgreementKeyMultibase, X25519_MULTIBASE_PREFIX, 'key-agreement key'),
115
+ updateKeyMultibase: requireKey(updateKey, ED25519_MULTIBASE_PREFIX, 'update key'),
116
+ stagedUpdateKeyMultibase: requireKey(stagedUpdateKeyMultibase, ED25519_MULTIBASE_PREFIX, 'staged update key')
117
+ };
118
+ }
119
+ /**
120
+ * The did:key a connect code's signing key derives -- shown on BOTH screens
121
+ * so the person running the ceremony can compare them before approving (the
122
+ * point-to-point verification the wrap and the document VM then inherit).
123
+ *
124
+ * @param options {object}
125
+ * @param options.request {EnrollmentRequest}
126
+ * @returns {string}
127
+ */
128
+ export function enrollmentClientDid({ request }) {
129
+ return `did:key:${request.signingKeyMultibase}`;
130
+ }
131
+ /**
132
+ * The kid of the enrollee's roster entry: its key-agreement key's id exactly
133
+ * as `agentsFromSeed` will derive it at the enrollee's own logins
134
+ * (`did:key:<ed-multibase>#<x-multibase>`), so the wrap minted here is the
135
+ * one its first roster read looks for.
136
+ *
137
+ * @param options {object}
138
+ * @param options.request {EnrollmentRequest}
139
+ * @returns {string}
140
+ */
141
+ export function enrollmentRecipientKid({ request }) {
142
+ return `${enrollmentClientDid({ request })}#${request.keyAgreementKeyMultibase}`;
143
+ }
144
+ /**
145
+ * ENROLLEE, step one: mints the new client's whole key set locally and
146
+ * returns it alongside the connect code to display. The caller holds the
147
+ * seeds in memory until the completion step persists them -- nothing is
148
+ * durable before the ceremony succeeds, so abandoning it leaks at most an
149
+ * orphan wrap on the enrolling side.
150
+ *
151
+ * @returns {Promise<object>} the in-memory key set, the code, and the
152
+ * client did:key to display beside it for comparison
153
+ */
154
+ export async function mintEnrollmentRequest() {
155
+ const clientSeed = crypto.getRandomValues(new Uint8Array(32));
156
+ const { keyAgent, keyAgreementKey } = await agentsFromSeed({
157
+ seed: clientSeed
158
+ });
159
+ const { publicKeyMultibase: keyAgreementKeyMultibase } = keyAgreementKey;
160
+ if (!keyAgreementKeyMultibase) {
161
+ throw new Error('The minted key-agreement key has no public multibase.');
162
+ }
163
+ const webvhUpdateKeys = await mintClientWebvhUpdateKeys();
164
+ const request = {
165
+ signingKeyMultibase: clientSigningKeyMultibase({ keyAgent }),
166
+ keyAgreementKeyMultibase,
167
+ updateKeyMultibase: await updateKeyMultibase({
168
+ seed: webvhUpdateKeys.updateSeed
169
+ }),
170
+ stagedUpdateKeyMultibase: await updateKeyMultibase({
171
+ seed: webvhUpdateKeys.stagedSeed
172
+ })
173
+ };
174
+ return {
175
+ clientSeed,
176
+ webvhUpdateKeys,
177
+ code: encodeEnrollmentRequest({ request }),
178
+ clientDid: keyAgent.id
179
+ };
180
+ }
181
+ /**
182
+ * ENROLLING CLIENT: the whole approval, in the push order -- the PUK wrapped
183
+ * into the roster first (escrow: every epoch, so the new client reads
184
+ * pre-enrollment history), then the two log entries. Quorum-of-one: this
185
+ * client's own update key signs both entries. Idempotent at every stage, so
186
+ * re-approving the same code after any tear converges.
187
+ *
188
+ * @param options {object}
189
+ * @param options.request {EnrollmentRequest} the parsed connect code
190
+ * @param options.clientWebvhKeys {ClientWebvhUpdateKeys} the approving
191
+ * client's own did:webvh update-key seeds
192
+ * @param options.clientKeyAgreementKey {IKeyAgreementKey} the approving
193
+ * client's own (identity) key-agreement key, unwrapping each epoch for
194
+ * re-wrapping
195
+ * @param options.pukRosterStore {MarkerStore} the account's
196
+ * `key-map/puk.json` marker store
197
+ * @param options.idStore {WebvhIdStore} the account's `id` collection
198
+ * @returns {Promise<{ did: string }>} the account's did:webvh
199
+ */
200
+ export async function approveEnrollment({ request, clientWebvhKeys, clientKeyAgreementKey, pukRosterStore, idStore }) {
201
+ // Decryption material before authorization: the wrap lands first, so no
202
+ // enrolled client is ever authorized but blind.
203
+ await addPukRosterRecipient({
204
+ store: pukRosterStore,
205
+ recipient: {
206
+ id: enrollmentRecipientKid({ request }),
207
+ publicKeyMultibase: request.keyAgreementKeyMultibase
208
+ },
209
+ ownerKeyAgreementKey: clientKeyAgreementKey
210
+ });
211
+ return enrollWebvhClient({
212
+ idStore,
213
+ updateKeys: clientWebvhKeys,
214
+ newClient: request
215
+ });
216
+ }
217
+ /**
218
+ * ENROLLEE, step two (after the other client approves): verifies the
219
+ * enrollment from the world-readable log and performs this client's first
220
+ * roster read -- signed with its just-published `<did:webvh>#<multibase>`
221
+ * key -- to obtain the PUK.
222
+ *
223
+ * The portable core of the completion step: the caller supplies the account
224
+ * pointer (from its own keyring lookup) and persists what comes back -- the
225
+ * PUK, the roster epoch to pin, and the key set itself -- under its own unlock
226
+ * layer. After that, an ordinary unlock finds an enrolled client.
227
+ *
228
+ * Throws `EnrollmentPendingError` while the add entry is not published yet
229
+ * (complete again once the other client finishes); any integrity failure
230
+ * (a log that resolves to a different DID than the account pointer names, a
231
+ * missing roster wrap) throws its own error.
232
+ *
233
+ * @param options {object}
234
+ * @param options.clientSeed {Uint8Array} from `mintEnrollmentRequest`
235
+ * @param options.webvhUpdateKeys {ClientWebvhUpdateKeys} from
236
+ * `mintEnrollmentRequest`
237
+ * @param options.pointer {AccountPointer} the account pointer the enrollee's
238
+ * keyring lookup recovered
239
+ * @returns {Promise<{ puk: Puk, latestEpochId: string }>}
240
+ */
241
+ export async function completeEnrollmentCore({ clientSeed, webvhUpdateKeys, pointer }) {
242
+ const did = pointer.did;
243
+ if (!did || !isWebvhDid(did)) {
244
+ throw new Error('The account pointer names no did:webvh; only a promoted account can ' +
245
+ 'enroll additional clients.');
246
+ }
247
+ const { keyAgent, keyAgreementKey } = await agentsFromSeed({
248
+ seed: clientSeed
249
+ });
250
+ // Verify the enrollment from the world-readable, self-certifying log: it
251
+ // must resolve to exactly the DID the account pointer names, and its
252
+ // document must list this client's keys -- the add entry has published.
253
+ const logUrl = new URL(`/space/${pointer.spaceId}/${ID_COLLECTION.id}/${DID_LOG_RESOURCE}`, pointer.host);
254
+ const response = await fetch(logUrl);
255
+ if (response.status === 404) {
256
+ throw new EnrollmentPendingError();
257
+ }
258
+ if (!response.ok) {
259
+ throw new Error(`Fetching the account's DID log failed (HTTP ${response.status}).`);
260
+ }
261
+ const resolved = await resolveDIDFromLog(readLogFromString(await response.text()));
262
+ if (resolved.meta.error || !resolved.did || !resolved.doc) {
263
+ throw new Error(`The account's DID log failed to resolve (${resolved.meta.error}).`);
264
+ }
265
+ if (resolved.did !== did) {
266
+ throw new Error('The published DID log resolves to a different DID than the account ' +
267
+ 'pointer names.');
268
+ }
269
+ const signingMultibase = clientSigningKeyMultibase({ keyAgent });
270
+ const updateKey = await updateKeyMultibase({
271
+ seed: webvhUpdateKeys.updateSeed
272
+ });
273
+ const enrolled = (resolved.doc.verificationMethod ?? []).some(method => method.publicKeyMultibase === signingMultibase) && (resolved.meta.updateKeys ?? []).includes(updateKey);
274
+ if (!enrolled) {
275
+ throw new EnrollmentPendingError();
276
+ }
277
+ // The first roster read: signed with the `<did:webvh>#<multibase>` keyId
278
+ // the add entry just published, unwrapping the PUK the enrolling client
279
+ // escrowed to this client's key-agreement key.
280
+ const zcapClient = webvhZcapClient({ keyAgent, did });
281
+ const store = pukRosterMarkerStore({
282
+ storageServerUrl: pointer.host,
283
+ zcapClient,
284
+ spaceId: pointer.spaceId
285
+ });
286
+ const read = await readPukRoster({
287
+ store,
288
+ clientKeyAgreementKey: keyAgreementKey
289
+ });
290
+ if (!read) {
291
+ throw new Error('The account has no PUK roster; it must finish provisioning before ' +
292
+ 'a client can be enrolled.');
293
+ }
294
+ return { puk: read.puk, latestEpochId: read.latestEpochId };
295
+ }
296
+ //# sourceMappingURL=enrollment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../src/enrollment/enrollment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/enrollment` subpath: the client enrollment
6
+ * ceremony -- connecting another wallet client to an existing account with
7
+ * only public halves travelling, point to point.
8
+ *
9
+ * - `mintEnrollmentRequest` / `encodeEnrollmentRequest` /
10
+ * `parseEnrollmentRequest` / `enrollmentClientDid` /
11
+ * `enrollmentRecipientKid` -- the connect-code channel layer.
12
+ * - `approveEnrollment` -- the enrolling client's half, in the push order
13
+ * (roster wrap, then the two did:webvh log entries).
14
+ * - `completeEnrollmentCore` -- the enrollee's half: verify from the published
15
+ * log, read the roster, hand back the PUK and the epoch to pin. Persisting
16
+ * the key set stays with the caller's own unlock layer.
17
+ */
18
+ export { approveEnrollment, completeEnrollmentCore, encodeEnrollmentRequest, EnrollmentPendingError, enrollmentClientDid, enrollmentRecipientKid, mintEnrollmentRequest, parseEnrollmentRequest } from './enrollment.js';
19
+ export type { EnrollmentRequest } from './enrollment.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/enrollment/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,iBAAiB,CAAA;AACxB,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,19 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/enrollment` subpath: the client enrollment
6
+ * ceremony -- connecting another wallet client to an existing account with
7
+ * only public halves travelling, point to point.
8
+ *
9
+ * - `mintEnrollmentRequest` / `encodeEnrollmentRequest` /
10
+ * `parseEnrollmentRequest` / `enrollmentClientDid` /
11
+ * `enrollmentRecipientKid` -- the connect-code channel layer.
12
+ * - `approveEnrollment` -- the enrolling client's half, in the push order
13
+ * (roster wrap, then the two did:webvh log entries).
14
+ * - `completeEnrollmentCore` -- the enrollee's half: verify from the published
15
+ * log, read the roster, hand back the PUK and the epoch to pin. Persisting
16
+ * the key set stays with the caller's own unlock layer.
17
+ */
18
+ export { approveEnrollment, completeEnrollmentCore, encodeEnrollmentRequest, EnrollmentPendingError, enrollmentClientDid, enrollmentRecipientKid, mintEnrollmentRequest, parseEnrollmentRequest } from './enrollment.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/enrollment/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,iBAAiB,CAAA"}
@@ -10,9 +10,6 @@
10
10
  * single-key resolver) under the fixed bootstrap handle / key name.
11
11
  * - `singleKeyResolver` -- the one-key `IKeyResolver` factory (also used by
12
12
  * app-side derivations such as a keyring unlock identity).
13
- * - `deriveCollectionKeys` -- per-collection vault-key (KAK) derivation:
14
- * `HKDF-SHA256(master seed, 'kak:v1:<collectionId>')` to a per-collection
15
- * seed, then the Ed25519-to-X25519 key-agreement key plus its resolver.
16
13
  *
17
14
  * Kept out of the root export: this subpath pulls the webkms-client / ezcap /
18
15
  * x25519 dependency graph (the same isolation pattern as `./request`).
@@ -20,6 +17,4 @@
20
17
  export { BOOTSTRAP_HANDLE, BOOTSTRAP_KEY_NAME, agentsFromSecret, agentsFromSeed } from './agents.js';
21
18
  export type { ProfileAgents } from './agents.js';
22
19
  export { singleKeyResolver } from './keyResolver.js';
23
- export { deriveCollectionKeys, DEFAULT_KAK_HANDLE } from './collectionKeys.js';
24
- export type { CollectionKeys } from './collectionKeys.js';
25
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC9E,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -10,14 +10,10 @@
10
10
  * single-key resolver) under the fixed bootstrap handle / key name.
11
11
  * - `singleKeyResolver` -- the one-key `IKeyResolver` factory (also used by
12
12
  * app-side derivations such as a keyring unlock identity).
13
- * - `deriveCollectionKeys` -- per-collection vault-key (KAK) derivation:
14
- * `HKDF-SHA256(master seed, 'kak:v1:<collectionId>')` to a per-collection
15
- * seed, then the Ed25519-to-X25519 key-agreement key plus its resolver.
16
13
  *
17
14
  * Kept out of the root export: this subpath pulls the webkms-client / ezcap /
18
15
  * x25519 dependency graph (the same isolation pattern as `./request`).
19
16
  */
20
17
  export { BOOTSTRAP_HANDLE, BOOTSTRAP_KEY_NAME, agentsFromSecret, agentsFromSeed } from './agents.js';
21
18
  export { singleKeyResolver } from './keyResolver.js';
22
- export { deriveCollectionKeys, DEFAULT_KAK_HANDLE } from './collectionKeys.js';
23
19
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/index.d.ts CHANGED
@@ -16,11 +16,24 @@
16
16
  * `interaction:` URL handling).
17
17
  * - `@interop/wallet-core/display` -- pure VC derivation / display helpers and
18
18
  * credential input parsing (raw values out; formatting stays in the UI).
19
+ * - `@interop/wallet-core/webvh` -- the account's did:webvh identity: the
20
+ * hosted DID log, its per-client update-key rotation, the client enrollment
21
+ * entries, and ZCap signing under the did:webvh verification-method id.
22
+ * - `@interop/wallet-core/keys` -- the per-user key (PUK) and its
23
+ * `key-map/puk.json` wrap-set roster.
24
+ * - `@interop/wallet-core/markers` -- collection-encryption marker
25
+ * acquisition (fetch / cache / offline fallback) and the unknown-epoch
26
+ * refresh policy, including a self-refreshing EDV document cipher.
27
+ * - `@interop/wallet-core/keyring` -- the unlock layer: the unlock derivation,
28
+ * the account-pointer record codec, and the unlock Space.
29
+ * - `@interop/wallet-core/enrollment` -- the client enrollment ceremony
30
+ * (connect code, approval, completion).
19
31
  *
20
32
  * This root re-exports `sync` and `space` for convenience. `identity`,
21
- * `request`, and `display` are deliberately NOT re-exported here, so plaintext
22
- * consumers of the root never pull the signing / KMS / document-loader
23
- * dependency graph (the was-client subpath-isolation pattern).
33
+ * `request`, `display`, `webvh`, `keys`, `markers`, `keyring`, and
34
+ * `enrollment` are deliberately NOT re-exported here, so plaintext consumers
35
+ * of the root never pull the signing / KMS / document-loader dependency graph
36
+ * (the was-client subpath-isolation pattern).
24
37
  */
25
38
  export * from './sync/index.js';
26
39
  export * from './space/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -16,11 +16,24 @@
16
16
  * `interaction:` URL handling).
17
17
  * - `@interop/wallet-core/display` -- pure VC derivation / display helpers and
18
18
  * credential input parsing (raw values out; formatting stays in the UI).
19
+ * - `@interop/wallet-core/webvh` -- the account's did:webvh identity: the
20
+ * hosted DID log, its per-client update-key rotation, the client enrollment
21
+ * entries, and ZCap signing under the did:webvh verification-method id.
22
+ * - `@interop/wallet-core/keys` -- the per-user key (PUK) and its
23
+ * `key-map/puk.json` wrap-set roster.
24
+ * - `@interop/wallet-core/markers` -- collection-encryption marker
25
+ * acquisition (fetch / cache / offline fallback) and the unknown-epoch
26
+ * refresh policy, including a self-refreshing EDV document cipher.
27
+ * - `@interop/wallet-core/keyring` -- the unlock layer: the unlock derivation,
28
+ * the account-pointer record codec, and the unlock Space.
29
+ * - `@interop/wallet-core/enrollment` -- the client enrollment ceremony
30
+ * (connect code, approval, completion).
19
31
  *
20
32
  * This root re-exports `sync` and `space` for convenience. `identity`,
21
- * `request`, and `display` are deliberately NOT re-exported here, so plaintext
22
- * consumers of the root never pull the signing / KMS / document-loader
23
- * dependency graph (the was-client subpath-isolation pattern).
33
+ * `request`, `display`, `webvh`, `keys`, `markers`, `keyring`, and
34
+ * `enrollment` are deliberately NOT re-exported here, so plaintext consumers
35
+ * of the root never pull the signing / KMS / document-loader dependency graph
36
+ * (the was-client subpath-isolation pattern).
24
37
  */
25
38
  export * from './sync/index.js';
26
39
  export * from './space/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,22 @@
1
+ import type { UnlockKdf } from './kdf.js';
2
+ import type { KeyringRecordContents } from './record.js';
3
+ /**
4
+ * Fetches and unwraps the keyring record an unlock secret addresses, or
5
+ * resolves `null` when no record exists there (an unknown secret). The derived
6
+ * unlock Space id is returned alongside the contents -- it is already computed,
7
+ * and callers key their local state on it.
8
+ *
9
+ * @param options {object}
10
+ * @param options.secret {string | Uint8Array} the unlock secret
11
+ * @param [options.kdf] {UnlockKdf} the unlock method's parameter set
12
+ * @param options.storageServerUrl {string} the WAS server origin
13
+ * @returns {Promise<(KeyringRecordContents & { unlockSpaceId: string }) | null>}
14
+ */
15
+ export declare function fetchKeyringRecord({ secret, kdf, storageServerUrl }: {
16
+ secret: string | Uint8Array;
17
+ kdf?: UnlockKdf;
18
+ storageServerUrl: string;
19
+ }): Promise<(KeyringRecordContents & {
20
+ unlockSpaceId: string;
21
+ }) | null>;
22
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/keyring/fetch.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAIzC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CAAC,EACvC,MAAM,EACN,GAAiB,EACjB,gBAAgB,EACjB,EAAE;IACD,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;IAC3B,GAAG,CAAC,EAAE,SAAS,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;CACzB,GAAG,OAAO,CAAC,CAAC,qBAAqB,GAAG;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC,CAkBtE"}