@interop/wallet-core 0.4.1 → 0.6.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 (73) 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/index.d.ts +13 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +13 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/keyring/fetch.d.ts +22 -0
  14. package/dist/keyring/fetch.d.ts.map +1 -0
  15. package/dist/keyring/fetch.js +35 -0
  16. package/dist/keyring/fetch.js.map +1 -0
  17. package/dist/keyring/index.d.ts +30 -0
  18. package/dist/keyring/index.d.ts.map +1 -0
  19. package/dist/keyring/index.js +28 -0
  20. package/dist/keyring/index.js.map +1 -0
  21. package/dist/keyring/kdf.d.ts +102 -0
  22. package/dist/keyring/kdf.d.ts.map +1 -0
  23. package/dist/keyring/kdf.js +148 -0
  24. package/dist/keyring/kdf.js.map +1 -0
  25. package/dist/keyring/record.d.ts +98 -0
  26. package/dist/keyring/record.d.ts.map +1 -0
  27. package/dist/keyring/record.js +119 -0
  28. package/dist/keyring/record.js.map +1 -0
  29. package/dist/keyring/unlockSpace.d.ts +101 -0
  30. package/dist/keyring/unlockSpace.d.ts.map +1 -0
  31. package/dist/keyring/unlockSpace.js +226 -0
  32. package/dist/keyring/unlockSpace.js.map +1 -0
  33. package/dist/keys/index.d.ts +24 -0
  34. package/dist/keys/index.d.ts.map +1 -0
  35. package/dist/keys/index.js +22 -0
  36. package/dist/keys/index.js.map +1 -0
  37. package/dist/keys/puk.d.ts +42 -0
  38. package/dist/keys/puk.d.ts.map +1 -0
  39. package/dist/keys/puk.js +56 -0
  40. package/dist/keys/puk.js.map +1 -0
  41. package/dist/keys/pukRoster.d.ts +210 -0
  42. package/dist/keys/pukRoster.d.ts.map +1 -0
  43. package/dist/keys/pukRoster.js +263 -0
  44. package/dist/keys/pukRoster.js.map +1 -0
  45. package/dist/keys/rosterStore.d.ts +18 -0
  46. package/dist/keys/rosterStore.d.ts.map +1 -0
  47. package/dist/keys/rosterStore.js +38 -0
  48. package/dist/keys/rosterStore.js.map +1 -0
  49. package/dist/space/collections.d.ts +57 -0
  50. package/dist/space/collections.d.ts.map +1 -1
  51. package/dist/space/collections.js +48 -0
  52. package/dist/space/collections.js.map +1 -1
  53. package/dist/space/index.d.ts +4 -0
  54. package/dist/space/index.d.ts.map +1 -1
  55. package/dist/space/index.js +4 -0
  56. package/dist/space/index.js.map +1 -1
  57. package/dist/webvh/didWeb.d.ts +41 -0
  58. package/dist/webvh/didWeb.d.ts.map +1 -0
  59. package/dist/webvh/didWeb.js +24 -0
  60. package/dist/webvh/didWeb.js.map +1 -0
  61. package/dist/webvh/didWebvh.d.ts +251 -0
  62. package/dist/webvh/didWebvh.d.ts.map +1 -0
  63. package/dist/webvh/didWebvh.js +775 -0
  64. package/dist/webvh/didWebvh.js.map +1 -0
  65. package/dist/webvh/index.d.ts +27 -0
  66. package/dist/webvh/index.d.ts.map +1 -0
  67. package/dist/webvh/index.js +24 -0
  68. package/dist/webvh/index.js.map +1 -0
  69. package/dist/webvh/zcap.d.ts +104 -0
  70. package/dist/webvh/zcap.d.ts.map +1 -0
  71. package/dist/webvh/zcap.js +117 -0
  72. package/dist/webvh/zcap.js.map +1 -0
  73. package/package.json +30 -4
@@ -0,0 +1,263 @@
1
+ import { addRecipient, initRecipients, ownerRecipient, unwrapEpochSecret, verifyEpochsMac } from '@interop/was-client/edv';
2
+ /**
3
+ * Thrown when a served roster fails its client-side authentication: a
4
+ * missing/unsupported/invalid `epochsMac`, or a marker whose `currentEpoch`
5
+ * names no epoch in its own list. The server (or whoever can write to it) has
6
+ * produced a configuration no enrolled client authenticated.
7
+ */
8
+ export class PukRosterIntegrityError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = 'PukRosterIntegrityError';
12
+ }
13
+ }
14
+ /**
15
+ * Thrown when a served roster conflicts with the locally pinned latest-seen
16
+ * epoch -- the epochs list no longer contains the pinned epoch, or
17
+ * `currentEpoch` precedes it in the (append-only) list. A rollback/replay of
18
+ * an older consistent configuration, which a valid `epochsMac` alone cannot
19
+ * catch; refused rather than followed.
20
+ */
21
+ export class PukRosterContinuityError extends Error {
22
+ pinnedEpochId;
23
+ constructor({ pinnedEpochId }) {
24
+ super('The PUK roster no longer carries the epoch this client has pinned -- ' +
25
+ 'a rolled-back or replayed roster.');
26
+ this.name = 'PukRosterContinuityError';
27
+ this.pinnedEpochId = pinnedEpochId;
28
+ }
29
+ }
30
+ /**
31
+ * Thrown when this client holds no usable wrap in the roster's current epoch
32
+ * (no recipient entry for its key-agreement key, or the entry fails to
33
+ * unwrap). The client cannot obtain the current PUK -- it may have been
34
+ * rotated off the roster.
35
+ */
36
+ export class PukRosterUnwrapError extends Error {
37
+ constructor(message) {
38
+ super(message);
39
+ this.name = 'PukRosterUnwrapError';
40
+ }
41
+ }
42
+ /**
43
+ * The fragment after the last `#` of a key/VM id -- for the ids this roster
44
+ * handles (did:key KAK ids, `<did>#<multibase>` VM ids) that fragment is the
45
+ * key's public multibase, which is what makes kid-to-VM matching key-material
46
+ * equality rather than string equality across id formats.
47
+ *
48
+ * @param id {string}
49
+ * @returns {string | undefined}
50
+ */
51
+ function multibaseFragmentOf(id) {
52
+ const hash = id.lastIndexOf('#');
53
+ return hash === -1 ? undefined : id.slice(hash + 1);
54
+ }
55
+ /**
56
+ * Builds the recipient resolver for roster rotations, backed by a locally
57
+ * verified did:webvh document -- the enforcement point for "the roster
58
+ * delivers, never sources". Given a remaining recipient's `kid`, it answers
59
+ * with that recipient's public key ONLY when the document carries a matching
60
+ * `keyAgreement` verification method (matched on the public-key multibase, so
61
+ * a did:key-form kid matches its `<did:webvh>#<multibase>` VM); otherwise it
62
+ * resolves `null` -- the was-client skip contract -- so the entry is dropped
63
+ * from the fresh epoch and never receives a wrap.
64
+ *
65
+ * @param options {object}
66
+ * @param options.document {RosterRecipientDocument} the locally verified
67
+ * did:webvh document (never a server-supplied roster field)
68
+ * @returns {function} a `resolveRecipientKey` for `removeRecipient`
69
+ */
70
+ export function pukRosterRecipientResolver({ document }) {
71
+ // Materialize the document's keyAgreement VMs once: embedded VMs verbatim,
72
+ // string references resolved against `verificationMethod`.
73
+ const byId = new Map();
74
+ for (const method of document.verificationMethod ?? []) {
75
+ if (typeof method?.id === 'string') {
76
+ byId.set(method.id, method);
77
+ }
78
+ }
79
+ const keyAgreementMethods = [];
80
+ for (const entry of document.keyAgreement ?? []) {
81
+ const method = typeof entry === 'string' ? byId.get(entry) : entry;
82
+ if (method && typeof method.publicKeyMultibase === 'string') {
83
+ keyAgreementMethods.push(method);
84
+ }
85
+ }
86
+ return async function resolveRecipientKey(kid) {
87
+ const fragment = multibaseFragmentOf(kid);
88
+ if (!fragment) {
89
+ return null;
90
+ }
91
+ const match = keyAgreementMethods.find(method => method.publicKeyMultibase === fragment ||
92
+ (typeof method.id === 'string' &&
93
+ multibaseFragmentOf(method.id) === fragment));
94
+ if (!match) {
95
+ // No document verification method backs this roster entry: drop it.
96
+ return null;
97
+ }
98
+ return { id: kid, publicKeyMultibase: match.publicKeyMultibase };
99
+ };
100
+ }
101
+ /**
102
+ * Ensures the roster exists, create-if-absent: an absent roster is
103
+ * initialized with the account's existing PUK installed as the first epoch,
104
+ * wrapped to this client's key-agreement key; an existing roster is returned
105
+ * as-is (authentication is the read path's job, and provisioning must never
106
+ * clobber an established roster). Idempotent -- losing the guarded-create
107
+ * race to a concurrent first init converges on the winner's roster.
108
+ *
109
+ * @param options {object}
110
+ * @param options.store {MarkerStore} the roster's marker store
111
+ * @param options.puk {Puk} the account's per-user key
112
+ * @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
113
+ * (identity) key-agreement key -- the roster recipient
114
+ * @returns {Promise<CollectionEncryption>} the roster marker
115
+ */
116
+ export async function ensurePukRoster({ store, puk, clientKeyAgreementKey }) {
117
+ const current = await store.read();
118
+ if (current !== null) {
119
+ return current.marker;
120
+ }
121
+ return initRecipients({
122
+ store,
123
+ recipients: [ownerRecipient({ keyAgreementKey: clientKeyAgreementKey })],
124
+ epoch: { epochId: puk.id, secret: puk.secret }
125
+ });
126
+ }
127
+ /**
128
+ * Wraps the PUK to a client being enrolled -- the roster half of the
129
+ * enrollment ceremony, and deliberately its FIRST write (decryption material
130
+ * before authorization, the push order): the wrap lands before the did:webvh
131
+ * log entries, so no enrolled client is ever authorized but blind, and a tear
132
+ * right after this write leaves only an orphan wrap -- invisible to
133
+ * authorization, harmless, resumed by re-running the ceremony.
134
+ *
135
+ * Escrow semantics ride on was-client's `addRecipient`: the new client
136
+ * receives EVERY epoch's key, current and prior, so it decrypts
137
+ * pre-enrollment history. The recipient key arrives over the point-to-point
138
+ * enrollment channel and is verified there by the enrolling client (the
139
+ * document VM it writes next comes from the same exchange) -- never sourced
140
+ * from the roster. Idempotent: a wrap already standing in the current epoch
141
+ * is returned as-is.
142
+ *
143
+ * @param options {object}
144
+ * @param options.store {MarkerStore} the roster's marker store
145
+ * @param options.recipient {RecipientPublicKey} the enrollee's public
146
+ * key-agreement key; `id` is the kid its own roster reads will look for
147
+ * @param options.ownerKeyAgreementKey {IKeyAgreementKey} the enrolling
148
+ * client's own (identity) key-agreement key, unwrapping each epoch for
149
+ * re-wrapping
150
+ * @returns {Promise<CollectionEncryption>} the refreshed roster marker
151
+ */
152
+ export async function addPukRosterRecipient({ store, recipient, ownerKeyAgreementKey }) {
153
+ const current = await store.read();
154
+ if (current === null) {
155
+ throw new Error('The PUK roster does not exist yet; the account must finish ' +
156
+ 'provisioning before a client can be enrolled.');
157
+ }
158
+ const marker = current.marker;
159
+ const currentEpoch = (marker.epochs ?? []).find(epoch => epoch.id === marker.currentEpoch);
160
+ const wrapped = currentEpoch?.recipients.some(entry => entry.header.kid === recipient.id);
161
+ if (wrapped) {
162
+ // A completed (or torn-after-the-wrap) earlier run: addRecipient writes
163
+ // every epoch's wrap in one marker write, so the current epoch standing
164
+ // means the escrow set is complete.
165
+ return marker;
166
+ }
167
+ return addRecipient({
168
+ store,
169
+ recipient,
170
+ owner: { keyAgreementKey: ownerKeyAgreementKey }
171
+ });
172
+ }
173
+ /**
174
+ * Reads and authenticates the roster -- the direct read at login and on epoch
175
+ * mismatch. Resolves `null` when the roster does not exist yet (an account
176
+ * provisioned before the roster, or provisioning still in flight); otherwise:
177
+ *
178
+ * 1. **Continuity**: the served epochs must contain the pinned latest-seen
179
+ * epoch, and `currentEpoch` must not precede it in the append-only list
180
+ * (`PukRosterContinuityError` -- the rollback/replay refusal).
181
+ * 2. **Possession**: `currentEpoch === puk.id` confirms the cached PUK
182
+ * current; otherwise the current epoch was rotated by another client and
183
+ * this client's wrap is unwrapped with its own key-agreement key
184
+ * (`PukRosterUnwrapError` when it holds none).
185
+ * 3. **Authentication**: the marker's `epochsMac` is verified under the
186
+ * current epoch's secret (`PukRosterIntegrityError` on any mismatch -- a
187
+ * fabricated configuration).
188
+ *
189
+ * A rotated read returns the fresh PUK; its Ed25519 signing seed does not
190
+ * travel through the roster (the roster wraps the key-agreement secret
191
+ * alone), so the returned PUK carries none.
192
+ *
193
+ * A caller with no cached PUK at all -- a freshly enrolled client making its
194
+ * first post-enrollment read -- omits `puk` and always takes the unwrap path;
195
+ * the result's `rotated` is then true (the PUK was adopted from the roster).
196
+ *
197
+ * @param options {object}
198
+ * @param options.store {MarkerStore} the roster's marker store
199
+ * @param [options.puk] {Puk} this client's cached PUK, when it holds one
200
+ * @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
201
+ * (identity) key-agreement key, unwrapping a rotated epoch
202
+ * @param [options.pinnedEpochId] {string} the locally pinned latest-seen
203
+ * roster epoch, when this client has seen the roster before
204
+ * @returns {Promise<PukRosterReadResult | null>}
205
+ */
206
+ export async function readPukRoster({ store, puk, clientKeyAgreementKey, pinnedEpochId }) {
207
+ const current = await store.read();
208
+ if (current === null) {
209
+ return null;
210
+ }
211
+ const marker = current.marker;
212
+ const epochIds = (marker.epochs ?? []).map(epoch => epoch.id);
213
+ const currentIndex = marker.currentEpoch
214
+ ? epochIds.indexOf(marker.currentEpoch)
215
+ : -1;
216
+ if (currentIndex === -1) {
217
+ throw new PukRosterIntegrityError('The PUK roster names no current epoch in its own epoch list.');
218
+ }
219
+ if (pinnedEpochId) {
220
+ const pinnedIndex = epochIds.indexOf(pinnedEpochId);
221
+ if (pinnedIndex === -1 || currentIndex < pinnedIndex) {
222
+ throw new PukRosterContinuityError({ pinnedEpochId });
223
+ }
224
+ }
225
+ // The epochsMac construction's own version/alg are the caller's to check.
226
+ const epochsMac = marker.epochsMac;
227
+ if (!epochsMac || epochsMac.v !== 1 || epochsMac.alg !== 'HS256') {
228
+ throw new PukRosterIntegrityError('The PUK roster carries no supported epoch-configuration MAC.');
229
+ }
230
+ let currentPuk;
231
+ let rotated;
232
+ if (puk && marker.currentEpoch === puk.id) {
233
+ currentPuk = puk;
234
+ rotated = false;
235
+ }
236
+ else {
237
+ // Rotated by another client: unwrap this client's entry in the current
238
+ // epoch with its own key-agreement key (rotation delivery).
239
+ const entry = marker.epochs[currentIndex].recipients.find(recipient => recipient.header.kid === clientKeyAgreementKey.id);
240
+ if (!entry) {
241
+ throw new PukRosterUnwrapError('The PUK roster current epoch carries no wrap for this client.');
242
+ }
243
+ const secret = await unwrapEpochSecret({
244
+ entry,
245
+ keyAgreementKey: clientKeyAgreementKey
246
+ });
247
+ if (!secret) {
248
+ throw new PukRosterUnwrapError("This client's PUK roster entry failed to unwrap.");
249
+ }
250
+ currentPuk = { id: marker.currentEpoch, secret };
251
+ rotated = true;
252
+ }
253
+ if (!(await verifyEpochsMac({ marker, epochSecret: currentPuk.secret }))) {
254
+ throw new PukRosterIntegrityError('The PUK roster epoch configuration failed authentication.');
255
+ }
256
+ return {
257
+ marker,
258
+ puk: currentPuk,
259
+ rotated,
260
+ latestEpochId: marker.currentEpoch
261
+ };
262
+ }
263
+ //# sourceMappingURL=pukRoster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pukRoster.js","sourceRoot":"","sources":["../../src/keys/pukRoster.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { ZcapClient } from '@interop/ezcap';
2
+ import { type MarkerStore } from '@interop/was-client/edv';
3
+ /**
4
+ * Builds the compare-and-swap marker store over `key-map/puk.json` in a data
5
+ * Space.
6
+ *
7
+ * @param options {object}
8
+ * @param options.storageServerUrl {string}
9
+ * @param options.zcapClient {ZcapClient} the session's root signing client
10
+ * @param options.spaceId {string} the data Space id
11
+ * @returns {MarkerStore}
12
+ */
13
+ export declare function pukRosterMarkerStore({ storageServerUrl, zcapClient, spaceId }: {
14
+ storageServerUrl: string;
15
+ zcapClient: ZcapClient;
16
+ spaceId: string;
17
+ }): MarkerStore;
18
+ //# sourceMappingURL=rosterStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAM/E;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,gBAAgB,EAChB,UAAU,EACV,OAAO,EACR,EAAE;IACD,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,WAAW,CAQd"}
@@ -0,0 +1,38 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The marker store over a Space's PUK wrap-set roster (`key-map/puk.json`).
6
+ * Standalone rather than a method on a wallet's remote-store class, because
7
+ * the login-time direct read checks the roster BEFORE any storage client (or
8
+ * cipher) is built: it takes the bare signing client instead of a store
9
+ * instance.
10
+ *
11
+ * The `plaintext` collection override is load-bearing. Without it the client
12
+ * decides plaintext vs encrypted by describing the collection first, and a 404
13
+ * from an absent Space or collection then surfaces as an encryption error
14
+ * rather than as an absent roster.
15
+ */
16
+ import { WasClient } from '@interop/was-client';
17
+ import { resourceMarkerStore } from '@interop/was-client/edv';
18
+ import { KEY_MAP_COLLECTION, PUK_ROSTER_RESOURCE } from '../space/collections.js';
19
+ /**
20
+ * Builds the compare-and-swap marker store over `key-map/puk.json` in a data
21
+ * Space.
22
+ *
23
+ * @param options {object}
24
+ * @param options.storageServerUrl {string}
25
+ * @param options.zcapClient {ZcapClient} the session's root signing client
26
+ * @param options.spaceId {string} the data Space id
27
+ * @returns {MarkerStore}
28
+ */
29
+ export function pukRosterMarkerStore({ storageServerUrl, zcapClient, spaceId }) {
30
+ const was = new WasClient({ serverUrl: storageServerUrl, zcapClient });
31
+ return resourceMarkerStore({
32
+ resource: was
33
+ .space(spaceId)
34
+ .collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' })
35
+ .resource(PUK_ROSTER_RESOURCE)
36
+ });
37
+ }
38
+ //# sourceMappingURL=rosterStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EAAE,mBAAmB,EAAoB,MAAM,yBAAyB,CAAA;AAC/E,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,yBAAyB,CAAA;AAEhC;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,gBAAgB,EAChB,UAAU,EACV,OAAO,EAKR;IACC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IACtE,OAAO,mBAAmB,CAAC;QACzB,QAAQ,EAAE,GAAG;aACV,KAAK,CAAC,OAAO,CAAC;aACd,UAAU,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;aAC9D,QAAQ,CAAC,mBAAmB,CAAC;KACjC,CAAC,CAAA;AACJ,CAAC"}
@@ -62,4 +62,61 @@ export declare const PUBLIC_CREDENTIALS_COLLECTION_SPEC: SpaceCollectionSpec;
62
62
  export declare const WALLET_ACTIVITY_COLLECTION_SPEC: SpaceCollectionSpec;
63
63
  /** The wallet Space's own (non-contacts) collection specs, in provision order. */
64
64
  export declare const WALLET_SPACE_COLLECTION_SPECS: SpaceCollectionSpec[];
65
+ /**
66
+ * The system collections and resource names that carry an account's identity
67
+ * and key material. They sit deliberately OUTSIDE the synced collection specs
68
+ * above: none of them gets a local replica or background replication, and each
69
+ * is read and written directly.
70
+ *
71
+ * - `id` -- world-readable (a collection-level public-read policy): the
72
+ * published DID document (`did.json`) and the did:webvh history log
73
+ * (`did.jsonl`). The path segments name the collection that holds the
74
+ * document, so the did:web id is `did:web:<host>:space:<spaceId>:id` and
75
+ * resolves to `https://<host>/space/<spaceId>/id/did.json`.
76
+ * - `key-map` -- private and capability-gated: the key-id map (`keys.json`)
77
+ * and the PUK wrap-set roster (`puk.json`). Kept separate from `id` exactly
78
+ * so `id` can be made world-readable without ever exposing key material.
79
+ * - `keyring` -- the unlock Space's single collection, holding the one
80
+ * keyring record (`keyring.json`). It lives in the minimal unlock Space
81
+ * controlled by an unlock identity, never in the wallet data Space.
82
+ */
83
+ export declare const ID_COLLECTION: {
84
+ id: string;
85
+ name: string;
86
+ };
87
+ export declare const KEY_MAP_COLLECTION: {
88
+ id: string;
89
+ name: string;
90
+ };
91
+ export declare const KEYRING_COLLECTION: {
92
+ id: string;
93
+ name: string;
94
+ };
95
+ /** The world-readable DID document, served as `application/did+json`. */
96
+ export declare const DID_DOCUMENT_RESOURCE = "did.json";
97
+ /**
98
+ * The world-readable did:webvh history log, a raw JSON-Lines string served as
99
+ * `text/jsonl`: one log entry per line, each a full DID-document snapshot in a
100
+ * hash chain. Sibling of `did.json` in the same `id` collection;
101
+ * `did:webvh:<scid>:<host>:space:<spaceId>:id` resolves to
102
+ * `https://<host>/space/<spaceId>/id/did.jsonl`.
103
+ */
104
+ export declare const DID_LOG_RESOURCE = "did.jsonl";
105
+ /**
106
+ * The (non-public) key-id map: verification method to KMS key id. Lives in the
107
+ * `key-map` collection. The recovery anchor -- written before `did.json` so a
108
+ * torn provisioning resumes from it.
109
+ */
110
+ export declare const DID_KEYS_RESOURCE = "keys.json";
111
+ /**
112
+ * The per-user-key (PUK) wrap-set roster, sibling of `keys.json` in the same
113
+ * private `key-map` collection: a `CollectionEncryption` marker stored
114
+ * verbatim as the resource body, whose current epoch IS the current PUK (the
115
+ * epoch id is the PUK's did:key; the wrapped secret is the PUK's raw key,
116
+ * wrapped to each enrolled client's key-agreement key). Read directly with a
117
+ * compare-and-swap etag -- never replicated.
118
+ */
119
+ export declare const PUK_ROSTER_RESOURCE = "puk.json";
120
+ /** The keyring record: the encrypted account pointer, in the unlock Space. */
121
+ export declare const KEYRING_RESOURCE = "keyring.json";
65
122
  //# sourceMappingURL=collections.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/space/collections.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AAEH,0EAA0E;AAC1E,eAAO,MAAM,8BAA8B,wBAAwB,CAAA;AACnE,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B,uBAAuB,CAAA;AACjE,0DAA0D;AAC1D,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,KAAK,GAAG,WAAW,CAAA;IAC/B,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,mBAMjD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,EAAE,mBAMhD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,mBAM7C,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,6BAA6B,EAAE,mBAAmB,EAI9D,CAAA"}
1
+ {"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/space/collections.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AAEH,0EAA0E;AAC1E,eAAO,MAAM,8BAA8B,wBAAwB,CAAA;AACnE,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B,uBAAuB,CAAA;AACjE,0DAA0D;AAC1D,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,KAAK,GAAG,WAAW,CAAA;IAC/B,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,mBAMjD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,EAAE,mBAMhD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,mBAM7C,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,6BAA6B,EAAE,mBAAmB,EAI9D,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa;;;CAAiC,CAAA;AAC3D,eAAO,MAAM,kBAAkB;;;CAAqC,CAAA;AACpE,eAAO,MAAM,kBAAkB;;;CAAqC,CAAA;AAEpE,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,aAAa,CAAA;AAC/C;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,cAAc,CAAA;AAC3C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,aAAa,CAAA;AAC7C,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,iBAAiB,CAAA"}
@@ -62,4 +62,52 @@ export const WALLET_SPACE_COLLECTION_SPECS = [
62
62
  PUBLIC_CREDENTIALS_COLLECTION_SPEC,
63
63
  WALLET_ACTIVITY_COLLECTION_SPEC
64
64
  ];
65
+ /**
66
+ * The system collections and resource names that carry an account's identity
67
+ * and key material. They sit deliberately OUTSIDE the synced collection specs
68
+ * above: none of them gets a local replica or background replication, and each
69
+ * is read and written directly.
70
+ *
71
+ * - `id` -- world-readable (a collection-level public-read policy): the
72
+ * published DID document (`did.json`) and the did:webvh history log
73
+ * (`did.jsonl`). The path segments name the collection that holds the
74
+ * document, so the did:web id is `did:web:<host>:space:<spaceId>:id` and
75
+ * resolves to `https://<host>/space/<spaceId>/id/did.json`.
76
+ * - `key-map` -- private and capability-gated: the key-id map (`keys.json`)
77
+ * and the PUK wrap-set roster (`puk.json`). Kept separate from `id` exactly
78
+ * so `id` can be made world-readable without ever exposing key material.
79
+ * - `keyring` -- the unlock Space's single collection, holding the one
80
+ * keyring record (`keyring.json`). It lives in the minimal unlock Space
81
+ * controlled by an unlock identity, never in the wallet data Space.
82
+ */
83
+ export const ID_COLLECTION = { id: 'id', name: 'Identity' };
84
+ export const KEY_MAP_COLLECTION = { id: 'key-map', name: 'Key Map' };
85
+ export const KEYRING_COLLECTION = { id: 'keyring', name: 'Keyring' };
86
+ /** The world-readable DID document, served as `application/did+json`. */
87
+ export const DID_DOCUMENT_RESOURCE = 'did.json';
88
+ /**
89
+ * The world-readable did:webvh history log, a raw JSON-Lines string served as
90
+ * `text/jsonl`: one log entry per line, each a full DID-document snapshot in a
91
+ * hash chain. Sibling of `did.json` in the same `id` collection;
92
+ * `did:webvh:<scid>:<host>:space:<spaceId>:id` resolves to
93
+ * `https://<host>/space/<spaceId>/id/did.jsonl`.
94
+ */
95
+ export const DID_LOG_RESOURCE = 'did.jsonl';
96
+ /**
97
+ * The (non-public) key-id map: verification method to KMS key id. Lives in the
98
+ * `key-map` collection. The recovery anchor -- written before `did.json` so a
99
+ * torn provisioning resumes from it.
100
+ */
101
+ export const DID_KEYS_RESOURCE = 'keys.json';
102
+ /**
103
+ * The per-user-key (PUK) wrap-set roster, sibling of `keys.json` in the same
104
+ * private `key-map` collection: a `CollectionEncryption` marker stored
105
+ * verbatim as the resource body, whose current epoch IS the current PUK (the
106
+ * epoch id is the PUK's did:key; the wrapped secret is the PUK's raw key,
107
+ * wrapped to each enrolled client's key-agreement key). Read directly with a
108
+ * compare-and-swap etag -- never replicated.
109
+ */
110
+ export const PUK_ROSTER_RESOURCE = 'puk.json';
111
+ /** The keyring record: the encrypted account pointer, in the unlock Space. */
112
+ export const KEYRING_RESOURCE = 'keyring.json';
65
113
  //# sourceMappingURL=collections.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"collections.js","sourceRoot":"","sources":["../../src/space/collections.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,8BAA8B,GAAG,qBAAqB,CAAA;AACnE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,6BAA6B,GAAG,oBAAoB,CAAA;AACjE,0DAA0D;AAC1D,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAA;AAyB3D;;;GAGG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAwB;IACtE,YAAY,EAAE,8BAA8B;IAC5C,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;CAChB,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAwB;IACrE,YAAY,EAAE,6BAA6B;IAC3C,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,WAAW;IACvB,QAAQ,EAAE,IAAI;CACf,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAwB;IAClE,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;CAChB,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,6BAA6B,GAA0B;IAClE,mCAAmC;IACnC,kCAAkC;IAClC,+BAA+B;CAChC,CAAA"}
1
+ {"version":3,"file":"collections.js","sourceRoot":"","sources":["../../src/space/collections.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,8BAA8B,GAAG,qBAAqB,CAAA;AACnE,2EAA2E;AAC3E,MAAM,CAAC,MAAM,6BAA6B,GAAG,oBAAoB,CAAA;AACjE,0DAA0D;AAC1D,MAAM,CAAC,MAAM,0BAA0B,GAAG,iBAAiB,CAAA;AAyB3D;;;GAGG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAwB;IACtE,YAAY,EAAE,8BAA8B;IAC5C,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;CAChB,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAwB;IACrE,YAAY,EAAE,6BAA6B;IAC3C,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,WAAW;IACvB,QAAQ,EAAE,IAAI;CACf,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAwB;IAClE,YAAY,EAAE,0BAA0B;IACxC,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;CAChB,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,6BAA6B,GAA0B;IAClE,mCAAmC;IACnC,kCAAkC;IAClC,+BAA+B;CAChC,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AACpE,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AAEpE,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAA;AAC/C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAA;AAC3C;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAA;AAC5C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAA;AAC7C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAA"}
@@ -8,6 +8,9 @@
8
8
  * - The shared collection ids and descriptive specs (`private-credentials`,
9
9
  * `public-credentials`, `wallet-activity`). The contacts collections stay in
10
10
  * `@interop/social-core`.
11
+ * - The system collections and resource names that carry identity and key
12
+ * material (`id`, `key-map`, `keyring`; `did.json`, `did.jsonl`, `keys.json`,
13
+ * `puk.json`, `keyring.json`) -- outside the synced set, never replicated.
11
14
  * - The `wallet-activity` wire shape (`WalletActivity`) and the pure
12
15
  * `addHistory*` payload builders.
13
16
  * - `publicCredentialUrl`, the world-readable shared-credential URL both
@@ -16,6 +19,7 @@
16
19
  * `parseWasLinkPayload` / `encodeWasLinkSecret`).
17
20
  */
18
21
  export { PRIVATE_CREDENTIALS_COLLECTION, PUBLIC_CREDENTIALS_COLLECTION, WALLET_ACTIVITY_COLLECTION, PRIVATE_CREDENTIALS_COLLECTION_SPEC, PUBLIC_CREDENTIALS_COLLECTION_SPEC, WALLET_ACTIVITY_COLLECTION_SPEC, WALLET_SPACE_COLLECTION_SPECS } from './collections.js';
22
+ export { ID_COLLECTION, KEY_MAP_COLLECTION, KEYRING_COLLECTION, DID_DOCUMENT_RESOURCE, DID_LOG_RESOURCE, DID_KEYS_RESOURCE, PUK_ROSTER_RESOURCE, KEYRING_RESOURCE } from './collections.js';
19
23
  export type { SpaceCollectionSpec } from './collections.js';
20
24
  export { ACTIVITY_TYPE, addHistoryNewAccount, addHistorySpaceCreated, addHistoryCredentialCreated, addHistoryCredentialDeleted, addHistoryCredentialShared, addHistoryCredentialUnshared, addHistoryLogin, addHistoryAppRevoke } from './activity.js';
21
25
  export type { WalletActivity, ActivityGrant } from './activity.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/space/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,0BAA0B,EAC1B,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,6BAA6B,EAC9B,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAE3D,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,eAAe,EACf,mBAAmB,EACpB,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/space/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,0BAA0B,EAC1B,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,6BAA6B,EAC9B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAE3D,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,eAAe,EACf,mBAAmB,EACpB,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA"}
@@ -8,6 +8,9 @@
8
8
  * - The shared collection ids and descriptive specs (`private-credentials`,
9
9
  * `public-credentials`, `wallet-activity`). The contacts collections stay in
10
10
  * `@interop/social-core`.
11
+ * - The system collections and resource names that carry identity and key
12
+ * material (`id`, `key-map`, `keyring`; `did.json`, `did.jsonl`, `keys.json`,
13
+ * `puk.json`, `keyring.json`) -- outside the synced set, never replicated.
11
14
  * - The `wallet-activity` wire shape (`WalletActivity`) and the pure
12
15
  * `addHistory*` payload builders.
13
16
  * - `publicCredentialUrl`, the world-readable shared-credential URL both
@@ -16,6 +19,7 @@
16
19
  * `parseWasLinkPayload` / `encodeWasLinkSecret`).
17
20
  */
18
21
  export { PRIVATE_CREDENTIALS_COLLECTION, PUBLIC_CREDENTIALS_COLLECTION, WALLET_ACTIVITY_COLLECTION, PRIVATE_CREDENTIALS_COLLECTION_SPEC, PUBLIC_CREDENTIALS_COLLECTION_SPEC, WALLET_ACTIVITY_COLLECTION_SPEC, WALLET_SPACE_COLLECTION_SPECS } from './collections.js';
22
+ export { ID_COLLECTION, KEY_MAP_COLLECTION, KEYRING_COLLECTION, DID_DOCUMENT_RESOURCE, DID_LOG_RESOURCE, DID_KEYS_RESOURCE, PUK_ROSTER_RESOURCE, KEYRING_RESOURCE } from './collections.js';
19
23
  export { ACTIVITY_TYPE, addHistoryNewAccount, addHistorySpaceCreated, addHistoryCredentialCreated, addHistoryCredentialDeleted, addHistoryCredentialShared, addHistoryCredentialUnshared, addHistoryLogin, addHistoryAppRevoke } from './activity.js';
20
24
  export { publicCredentialUrl } from './publicLink.js';
21
25
  export { encodeWasLinkSecret, buildWasLinkPayload, parseWasLinkPayload } from './wasLink.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/space/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,0BAA0B,EAC1B,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,6BAA6B,EAC9B,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,eAAe,EACf,mBAAmB,EACpB,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/space/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC7B,0BAA0B,EAC1B,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,6BAA6B,EAC9B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,eAAe,EACf,mBAAmB,EACpB,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAErD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,41 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The did:web relationship map the did:webvh module round-trips: the durable
6
+ * `keys.json` binding from DID relationship to KMS key, plus the fragment
7
+ * helper both documents' verification-method ids are read through. A KMS key's
8
+ * public alias expands `{publicKeyMultibase}` at generate time, so a
9
+ * verification-method id already carries the key's `publicKeyMultibase` and no
10
+ * separate key-description fetch is ever needed.
11
+ */
12
+ /**
13
+ * One verification method's durable binding: the verification-method id (the
14
+ * did:web `#fragment` URL, which is also the KMS key's publicAlias) and the
15
+ * KMS key id used to invoke signing.
16
+ */
17
+ export interface DidWebKey {
18
+ vmId: string;
19
+ kmsKeyId: string;
20
+ }
21
+ /**
22
+ * The key-id map persisted as `keys.json` in the private `key-map` collection:
23
+ * the durable mapping from DID relationship to KMS key, since the KMS protocol
24
+ * has no list-keys endpoint and key ids are server-generated.
25
+ */
26
+ export interface DidWebKeyMap {
27
+ authentication: DidWebKey;
28
+ assertionMethod: DidWebKey;
29
+ keyAgreement: DidWebKey;
30
+ }
31
+ /**
32
+ * The bare `publicKeyMultibase` a KMS key alias or verification-method id
33
+ * carries in its fragment. The KMS expanded `#{publicKeyMultibase}` at generate
34
+ * time, so the fragment IS the multibase key (no separate key-description fetch
35
+ * needed).
36
+ *
37
+ * @param id {string}
38
+ * @returns {string}
39
+ */
40
+ export declare function multibaseOf(id: string): string;
41
+ //# sourceMappingURL=didWeb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"didWeb.d.ts","sourceRoot":"","sources":["../../src/webvh/didWeb.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,SAAS,CAAA;IACzB,eAAe,EAAE,SAAS,CAAA;IAC1B,YAAY,EAAE,SAAS,CAAA;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C"}
@@ -0,0 +1,24 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The did:web relationship map the did:webvh module round-trips: the durable
6
+ * `keys.json` binding from DID relationship to KMS key, plus the fragment
7
+ * helper both documents' verification-method ids are read through. A KMS key's
8
+ * public alias expands `{publicKeyMultibase}` at generate time, so a
9
+ * verification-method id already carries the key's `publicKeyMultibase` and no
10
+ * separate key-description fetch is ever needed.
11
+ */
12
+ /**
13
+ * The bare `publicKeyMultibase` a KMS key alias or verification-method id
14
+ * carries in its fragment. The KMS expanded `#{publicKeyMultibase}` at generate
15
+ * time, so the fragment IS the multibase key (no separate key-description fetch
16
+ * needed).
17
+ *
18
+ * @param id {string}
19
+ * @returns {string}
20
+ */
21
+ export function multibaseOf(id) {
22
+ return id.slice(id.lastIndexOf('#') + 1);
23
+ }
24
+ //# sourceMappingURL=didWeb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"didWeb.js","sourceRoot":"","sources":["../../src/webvh/didWeb.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AAuBH;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;AAC1C,CAAC"}