@interop/was-react 0.4.0 → 0.5.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 (57) hide show
  1. package/README.md +84 -11
  2. package/dist/auth/loginFlow.d.ts +6 -0
  3. package/dist/auth/loginFlow.d.ts.map +1 -1
  4. package/dist/auth/loginFlow.js +28 -9
  5. package/dist/auth/loginFlow.js.map +1 -1
  6. package/dist/auth/loginRequest.d.ts +22 -1
  7. package/dist/auth/loginRequest.d.ts.map +1 -1
  8. package/dist/auth/loginRequest.js +17 -1
  9. package/dist/auth/loginRequest.js.map +1 -1
  10. package/dist/config.d.ts +51 -0
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +0 -0
  13. package/dist/config.js.map +1 -1
  14. package/dist/identity/agents.d.ts +38 -11
  15. package/dist/identity/agents.d.ts.map +1 -1
  16. package/dist/identity/agents.js +35 -11
  17. package/dist/identity/agents.js.map +1 -1
  18. package/dist/identity/initAppSession.d.ts +6 -6
  19. package/dist/identity/initAppSession.js +6 -6
  20. package/dist/identity/seedCredential.d.ts +29 -5
  21. package/dist/identity/seedCredential.d.ts.map +1 -1
  22. package/dist/identity/seedCredential.js +47 -11
  23. package/dist/identity/seedCredential.js.map +1 -1
  24. package/dist/index.d.ts +7 -6
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +8 -6
  27. package/dist/index.js.map +1 -1
  28. package/dist/react/hooks.d.ts +12 -0
  29. package/dist/react/hooks.d.ts.map +1 -1
  30. package/dist/react/hooks.js +14 -0
  31. package/dist/react/hooks.js.map +1 -1
  32. package/dist/react/index.d.ts +1 -1
  33. package/dist/react/index.d.ts.map +1 -1
  34. package/dist/react/index.js +1 -1
  35. package/dist/react/index.js.map +1 -1
  36. package/dist/session/authStore.d.ts +9 -0
  37. package/dist/session/authStore.d.ts.map +1 -1
  38. package/dist/session/authStore.js +41 -16
  39. package/dist/session/authStore.js.map +1 -1
  40. package/dist/storage/adopt.js +2 -2
  41. package/dist/storage/localStore.d.ts +27 -16
  42. package/dist/storage/localStore.d.ts.map +1 -1
  43. package/dist/storage/localStore.js +38 -31
  44. package/dist/storage/localStore.js.map +1 -1
  45. package/dist/storage/sharedCollectionReader.d.ts +95 -0
  46. package/dist/storage/sharedCollectionReader.d.ts.map +1 -0
  47. package/dist/storage/sharedCollectionReader.js +338 -0
  48. package/dist/storage/sharedCollectionReader.js.map +1 -0
  49. package/dist/storage/wasSync.d.ts +37 -5
  50. package/dist/storage/wasSync.d.ts.map +1 -1
  51. package/dist/storage/wasSync.js +45 -5
  52. package/dist/storage/wasSync.js.map +1 -1
  53. package/dist/sync/docCipher.d.ts +3 -2
  54. package/dist/sync/docCipher.d.ts.map +1 -1
  55. package/dist/sync/docCipher.js +3 -2
  56. package/dist/sync/docCipher.js.map +1 -1
  57. package/package.json +3 -3
package/README.md CHANGED
@@ -94,13 +94,16 @@ export const config: WasAppConfig = {
94
94
  `collections` maps each app-side `key` (the local RxDB collection handle) to a
95
95
  WAS collection `id` (a deliberately unprefixed, generic name shared across
96
96
  interoperable apps). `credential` names the self-issued seed credential the
97
- first-run flow mints. All other fields (`mediatorBase`, `dbName`,
98
- `storageKeyPrefix`, `sync`, `expiry`) are optional with documented defaults.
97
+ first-run flow mints; its `vocabBase` namespaces the app's own type term only,
98
+ since every app key also carries the shared `AppKeyCredential` marker type and
99
+ its `seed` / `origin` claims under `urn:was:` IRIs. All other fields
100
+ (`mediatorBase`, `dbName`, `storageKeyPrefix`, `sync`, `expiry`) are optional
101
+ with documented defaults.
99
102
 
100
103
  A collection may also declare `visibility: 'public'`
101
104
  (`{ key: 'posts', id: 'microblog-posts', visibility: 'public' }`); the default
102
105
  is `'private'`. A public collection is world-readable and therefore PLAINTEXT:
103
- no per-collection key is derived, payloads are stored as-is locally and
106
+ no encryption key is involved at all, payloads are stored as-is locally and
104
107
  remotely, and the stored resource id is the payload's own logical `id`, so a
105
108
  public document keeps a stable, shareable resource URL across edits. Be aware
106
109
  that everything in a public payload is world-readable -- including the LWW
@@ -126,6 +129,70 @@ feature fails closed with older wallets. Publicness is granted at consent time
126
129
  by the wallet -- the app itself can never escalate an existing private
127
130
  collection to public.
128
131
 
132
+ #### Shared (wallet-owned) collections
133
+
134
+ `collections` above are collections this app OWNS: the wallet provisions them,
135
+ the app writes them, and they replicate into the local replica. A third kind is
136
+ read-only and belongs to the wallet -- one of the wallet's own encrypted
137
+ collections (`private-credentials`, `wallet-activity`, `contacts`,
138
+ `contacts-history`) that the user chooses to share with this app. Declare those
139
+ separately:
140
+
141
+ ```ts
142
+ sharedCollections: [{ key: 'walletCredentials', id: 'private-credentials' }]
143
+ ```
144
+
145
+ A shared collection is read-only by construction. It is never replicated into
146
+ RxDB, never written to, has no local replica, and is excluded from the sync
147
+ bootstrap's collection-description writes. Reads go straight to the server
148
+ through a `SharedCollectionReader`, looked up by its `key`:
149
+
150
+ ```ts
151
+ const shared = useSharedCollection('walletCredentials')
152
+ const items = (await shared?.list()) ?? []
153
+ const one = await shared?.get(items[0].id)
154
+ ```
155
+
156
+ `list()` reads the collection by paging the WAS `changes` feed, which returns
157
+ whole pages of documents with their bodies -- and on an encrypted collection
158
+ those bodies are the opaque EDV envelopes the reader wants, since the feed does
159
+ not decrypt. That is one request per page rather than one per credential.
160
+ Tombstones are skipped, so the result is the live set. A backend that does not
161
+ support the `changes-query` feature answers 501; the reader then falls back to
162
+ listing the resource summaries and fetching each body, warning once that the
163
+ collection is being read the slow way. `SharedCollectionReader.open` takes an
164
+ optional `pageSize` (default `SHARED_CHANGES_PAGE_SIZE`, 100).
165
+
166
+ A collection may be app-owned or shared, never both; a registry that declares
167
+ the same `key` or `id` in each is rejected at store open
168
+ (`validateSharedCollections`).
169
+
170
+ At login each shared collection is requested with the distinct
171
+ `urn:was:shared-collection` descriptor type and the read-only action set
172
+ `SHARED_ACTIONS` (`GET`/`HEAD`) -- an app never asks to write a wallet
173
+ collection. As with `urn:was:public-collection`, a wallet that predates the type
174
+ reports the request unsatisfiable and the feature fails closed, which is the
175
+ point: a share fuses two axes -- the read zcap AND an entry in the collection's
176
+ key-epoch roster -- and a wallet that granted only the zcap would hand the app
177
+ ciphertext it cannot decrypt, surfacing as corrupt data rather than as a wallet
178
+ that needs updating.
179
+
180
+ Decryption uses the app's **identity** key-agreement key: the X25519 twin of its
181
+ `did:key` controller (`IdentityAgents.keyAgreementKey`), which is exactly what
182
+ the wallet derives from the controller DID when it writes the app into the
183
+ roster, so the recipient key never travels on the wire. It is the same key the
184
+ app's own collections are encrypted with -- an epoch-roster recipient is always
185
+ the X25519 twin of a controller did:key, whoever owns the collection.
186
+
187
+ Two honest limits, the same ones the wallet's consent screen states. Access can
188
+ be removed later, which stops future reads but cannot take back what has already
189
+ been read. And resources written BEFORE the collection was first shared are
190
+ sealed to the owner alone and are never re-encrypted -- they will not decrypt
191
+ here. Both `list()` and `get()` skip such a resource with a warning rather than
192
+ failing; a collection this app is not a recipient of at all fails at open time
193
+ with a `SharedCollectionUnavailableError`, and the session continues without
194
+ that reader.
195
+
129
196
  ### 2. Entity stores and the registry
130
197
 
131
198
  ```ts
@@ -330,7 +397,8 @@ Login is driven by CHAPI Verifiable Presentation Requests (VPRs). The
330
397
  dismissed store would silently break cross-device recovery.
331
398
  4. **Returning login: recover and verify.** When the probe returns the seed
332
399
  credential, `parseSeedCredential` recovers the seed and cryptographically
333
- verifies the credential is self-issued, origin-bound, and seed-to-DID bound.
400
+ verifies the credential carries the shared `AppKeyCredential` marker type and
401
+ is self-issued, origin-bound, and seed-to-DID bound.
334
402
  5. **Derive identity.** The stable `did:key` controller and its signer are
335
403
  derived deterministically from the seed via `CapabilityAgent.fromSeed`
336
404
  (`initAppSession` / `deriveIdentity`). The same seed yields the same identity
@@ -390,13 +458,18 @@ Hooks:
390
458
  row is `{ id, updatedAt, version, data }`, where `data` is an EDV envelope
391
459
  `{ id, sequence, jwe }`. The app reads exclusively from the in-memory entity
392
460
  stores hydrated from this replica, so it works fully offline.
393
- - **Envelope encryption.** Each private collection is encrypted with its own
394
- X25519 key-agreement key, HKDF-derived from the master seed with the label
395
- `kak:v1:<collectionId>` (`deriveCollectionKeys`). HKDF one-wayness means a
396
- shared per-collection key exposes nothing about the master seed or the sibling
397
- collections. The WAS server never sees plaintext. A collection declared
398
- `visibility: 'public'` opts out entirely: payloads are stored plaintext (no
399
- key derivation, no envelope) behind the same storage seam.
461
+ - **Envelope encryption.** Every private collection is encrypted with the app's
462
+ identity X25519 key-agreement key -- the twin of its `did:key` controller,
463
+ derived once per session and shared by all of them, which is also the key a
464
+ wallet writes into a roster when it shares one of its OWN collections. One key
465
+ therefore reads everything this app touches (earlier versions derived a
466
+ separate HKDF key per collection; see "One key identity" in ARCHITECTURE.md
467
+ for why that separation was given up). The WAS server never sees plaintext. A
468
+ collection declared `visibility: 'public'` opts out entirely: payloads are
469
+ stored plaintext (no key, no envelope) behind the same storage seam. A SHARED
470
+ (wallet-owned) collection is outside the replica: it never replicates and has
471
+ no local rows, and its envelopes are decrypted on demand with that same
472
+ identity key through the collection's key-epoch roster.
400
473
  - **Replication.** A per-session `SyncController` runs RxDB replication per
401
474
  collection over a `WasSyncPort` (signed requests authorized by the granted
402
475
  zcaps). Pull is driven by the WAS `changes` feed; a low-frequency periodic
@@ -48,6 +48,12 @@ export interface LoginConfig {
48
48
  * visibility; `'public'` selects the `urn:was:public-collection` descriptor).
49
49
  */
50
50
  collections: GrantRequestCollection[];
51
+ /**
52
+ * WAS collection ids of wallet-owned collections to request read-and-decrypt
53
+ * access to (the `urn:was:shared-collection` grant). Read-only; never
54
+ * replicated.
55
+ */
56
+ sharedCollections?: string[];
51
57
  /**
52
58
  * The seed-credential type name + vocabulary namespace.
53
59
  */
@@ -1 +1 @@
1
- {"version":3,"file":"loginFlow.d.ts","sourceRoot":"","sources":["../../src/auth/loginFlow.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAEV,KAAK,EACN,MAAM,8BAA8B,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,+BAA+B,CAAA;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,WAAW,EAAE,sBAAsB,EAAE,CAAA;IACrC;;OAEG;IACH,UAAU,EAAE,oBAAoB,CAAA;IAChC;;OAEG;IACH,cAAc,EAAE,cAAc,CAAA;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,CAAA;AAEnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,MAAM,EAAE,YAAY,CAAA;IACpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,IAAI,EAAE,MAAM;CAIzB;AAED;;;;;GAKG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;;CAQhD;AAwDD;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,OAAO,EACR,EAAE;IACD,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACtC,GAAG,OAAO,CAAC,aAAa,CAAC,CA+BzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,EACpC,MAAM,EACN,OAAO,EACR,EAAE;IACD,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACtC,GAAG,OAAO,CAAC,YAAY,CAAC,CAgExB"}
1
+ {"version":3,"file":"loginFlow.d.ts","sourceRoot":"","sources":["../../src/auth/loginFlow.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAEV,KAAK,EACN,MAAM,8BAA8B,CAAA;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,+BAA+B,CAAA;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,WAAW,EAAE,sBAAsB,EAAE,CAAA;IACrC;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B;;OAEG;IACH,UAAU,EAAE,oBAAoB,CAAA;IAChC;;OAEG;IACH,cAAc,EAAE,cAAc,CAAA;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,CAAA;AAEnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,MAAM,EAAE,YAAY,CAAA;IACpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,IAAI,EAAE,MAAM;CAIzB;AAED;;;;;GAKG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;;CAQhD;AAiED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,OAAO,EACR,EAAE;IACD,QAAQ,EAAE,cAAc,CAAA;IACxB,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACtC,GAAG,OAAO,CAAC,aAAa,CAAC,CAqCzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CAAC,EACpC,MAAM,EACN,OAAO,EACR,EAAE;IACD,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACtC,GAAG,OAAO,CAAC,YAAY,CAAC,CAsExB"}
@@ -42,20 +42,27 @@ function appConnectFirstRun(presentation) {
42
42
  }
43
43
  /**
44
44
  * Structurally validates the grants embedded in the wallet response against the
45
- * requested collections. When the app requested NO collections there is nothing
46
- * to delegate: `checkGrants` (which rejects an empty grant set) is skipped and
47
- * an empty grant set with a far-future expiry is returned instead.
45
+ * requested collections. When the app requested NO collections at all (neither
46
+ * app-owned nor shared) there is nothing to delegate: `checkGrants` (which
47
+ * rejects an empty grant set) is skipped and an empty grant set with a
48
+ * far-future expiry is returned instead.
49
+ *
50
+ * Only the app-owned collections are REQUIRED to be covered. A shared
51
+ * collection the wallet declined to grant is not a login failure -- the reader
52
+ * for it is simply not opened, with a warning -- so its id is not passed to
53
+ * `checkGrants`; it still reaches the routing table through `parseGrants`.
48
54
  *
49
55
  * @param options {object}
50
56
  * @param options.presentation {IVerifiablePresentation}
51
57
  * @param options.controllerDid {string} the app-key subject DID grants must
52
58
  * be controlled by
53
59
  * @param options.collections {GrantRequestCollection[]}
60
+ * @param [options.sharedCollections] {string[]}
54
61
  * @returns {CheckedGrants}
55
62
  */
56
- function checkGrantsForCollections({ presentation, controllerDid, collections }) {
63
+ function checkGrantsForCollections({ presentation, controllerDid, collections, sharedCollections = [] }) {
57
64
  const collectionIds = collections.map(collection => collection.id);
58
- if (collectionIds.length === 0) {
65
+ if (collectionIds.length === 0 && sharedCollections.length === 0) {
59
66
  return {
60
67
  grants: [],
61
68
  parsed: { serverUrl: '', spaceId: '', byCollectionId: {} },
@@ -88,7 +95,10 @@ export async function requestGrants({ identity, config, onPhase }) {
88
95
  domain: window.location.origin,
89
96
  appName: config.appName,
90
97
  credential: config.credential,
91
- collections: config.collections
98
+ collections: config.collections,
99
+ ...(config.sharedCollections && {
100
+ sharedCollections: config.sharedCollections
101
+ })
92
102
  });
93
103
  const presentation = await chapiGet({
94
104
  vpr,
@@ -109,7 +119,10 @@ export async function requestGrants({ identity, config, onPhase }) {
109
119
  return checkGrantsForCollections({
110
120
  presentation,
111
121
  controllerDid: identity.controllerDid,
112
- collections: config.collections
122
+ collections: config.collections,
123
+ ...(config.sharedCollections && {
124
+ sharedCollections: config.sharedCollections
125
+ })
113
126
  });
114
127
  }
115
128
  /**
@@ -134,7 +147,10 @@ export async function loginWithWallet({ config, onPhase }) {
134
147
  domain: window.location.origin,
135
148
  appName: config.appName,
136
149
  credential: config.credential,
137
- collections: config.collections
150
+ collections: config.collections,
151
+ ...(config.sharedCollections && {
152
+ sharedCollections: config.sharedCollections
153
+ })
138
154
  });
139
155
  const presentation = await chapiGet({
140
156
  vpr,
@@ -178,7 +194,10 @@ export async function loginWithWallet({ config, onPhase }) {
178
194
  const checked = checkGrantsForCollections({
179
195
  presentation,
180
196
  controllerDid: parsedCredential.controllerDid,
181
- collections: config.collections
197
+ collections: config.collections,
198
+ ...(config.sharedCollections && {
199
+ sharedCollections: config.sharedCollections
200
+ })
182
201
  });
183
202
  return {
184
203
  seed,
@@ -1 +1 @@
1
- {"version":3,"file":"loginFlow.js","sourceRoot":"","sources":["../../src/auth/loginFlow.ts"],"names":[],"mappings":"AA6BA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAE9D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EACL,kBAAkB,EAClB,YAAY,EAEb,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,WAAW,EACX,QAAQ,EACR,uBAAuB,EAExB,MAAM,qBAAqB,CAAA;AA0D5B;;GAEG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,IAAY;QACtB,KAAK,CAAC,qCAAqC,IAAI,IAAI,CAAC,CAAA;QACpD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C;QACE,KAAK,CACH,qEAAqE;YACnE,SAAS,CACZ,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAA;IACtC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,mBAAmB,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAE3D;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,YAAqC;IAC/D,MAAM,UAAU,GAAI,YAAwD;SACzE,UAAU,CAAA;IACb,OAAO,UAAU,EAAE,QAAQ,KAAK,IAAI,CAAA;AACtC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,yBAAyB,CAAC,EACjC,YAAY,EACZ,aAAa,EACb,WAAW,EAKZ;IACC,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAClE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE;YAC1D,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,mBAAmB,CAAC,CAAC,WAAW,EAAE;SAClE,CAAA;IACH,CAAC;IACD,OAAO,WAAW,CAAC;QACjB,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC;QAC9B,aAAa;QACb,WAAW,EAAE,aAAa;KAC3B,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,OAAO,EAKR;IACC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAA;IACvB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,GAAG,GAAG,kBAAkB,CAAC;QAC7B,SAAS;QACT,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAA;IACF,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC;QAClC,GAAG;QACH,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI;YACvC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC;KACH,CAAC,CAAA;IACF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAmB,CAAC,gBAAgB,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,EAAE,CAAC,WAAW,CAAC,CAAA;IACtB,MAAM,uBAAuB,CAAC;QAC5B,YAAY;QACZ,SAAS;QACT,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAA;IACF,OAAO,yBAAyB,CAAC;QAC/B,YAAY;QACZ,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,MAAM,EACN,OAAO,EAIR;IACC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAA;IACvB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,GAAG,GAAG,kBAAkB,CAAC;QAC7B,SAAS;QACT,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAA;IACF,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC;QAClC,GAAG;QACH,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,IAAI;YACvC,YAAY,EAAE,MAAM,CAAC,YAAY;SAClC,CAAC;KACH,CAAC,CAAA;IACF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAmB,CAAC,cAAc,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,EAAE,CAAC,WAAW,CAAC,CAAA;IACtB,MAAM,uBAAuB,CAAC;QAC5B,YAAY;QACZ,SAAS;QACT,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAA;IAEF,2EAA2E;IAC3E,uEAAuE;IACvE,2EAA2E;IAC3E,sBAAsB;IACtB,MAAM,UAAU,GAAG,kBAAkB,CAAC;QACpC,YAAY;QACZ,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,cAAc;KACjD,CAAC,CAAA;IACF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,sBAAsB,EAAE,CAAA;IACpC,CAAC;IACD,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC;QACjD,UAAU;QACV,MAAM,EAAE,MAAM,CAAC,SAAS;QACxB,MAAM,EAAE,MAAM,CAAC,UAAU;KAC1B,CAAC,CAAA;IACF,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAA;IAClC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAA;IAEjD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/C,8EAA8E;IAC9E,+BAA+B;IAC/B,MAAM,OAAO,GAAG,yBAAyB,CAAC;QACxC,YAAY;QACZ,aAAa,EAAE,gBAAgB,CAAC,aAAa;QAC7C,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAA;IACF,OAAO;QACL,IAAI;QACJ,QAAQ;QACR,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,QAAQ;KACT,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"loginFlow.js","sourceRoot":"","sources":["../../src/auth/loginFlow.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,17 @@
23
23
  * whole is likewise unsatisfiable on a wallet that predates it, so an old wallet
24
24
  * fails closed rather than degrading into a partial generic flow.
25
25
  *
26
+ * A SHARED collection -- one the wallet already owns and encrypts, which the app
27
+ * asks to read and decrypt -- uses the `urn:was:shared-collection` descriptor
28
+ * type, and the actions are read-only by construction ({@link SHARED_ACTIONS}):
29
+ * the app never requests writes on a wallet collection. Exactly like
30
+ * `urn:was:public-collection`, a wallet that predates the type resolves the
31
+ * descriptor UNSATISFIABLE and fails closed -- which is the point here. A share
32
+ * fuses two axes (a read zcap AND an entry in the collection's key-epoch
33
+ * roster), so a wallet that granted only the zcap would hand the app ciphertext
34
+ * it cannot decrypt; that would surface as corrupt data rather than as a wallet
35
+ * that needs updating.
36
+ *
26
37
  * `domain` must host-match the CHAPI requesting origin or the wallet refuses
27
38
  * to sign; `challenge` must be fresh per request (echoed into the DIDAuth
28
39
  * proof and checked in verifyResponse).
@@ -33,6 +44,12 @@ import type { IVPRDetails } from './walletRequestTypes.js';
33
44
  * Default read/write actions requested on each app collection.
34
45
  */
35
46
  export declare const RW_ACTIONS: string[];
47
+ /**
48
+ * The actions requested on a SHARED (wallet-owned) collection: read-only, and
49
+ * not configurable. A shared collection belongs to the wallet, so an app never
50
+ * asks to write it.
51
+ */
52
+ export declare const SHARED_ACTIONS: string[];
36
53
  /**
37
54
  * One collection to request a grant for: the WAS collection id plus its
38
55
  * declared visibility (`'private'`, the default, or `'public'`).
@@ -75,16 +92,20 @@ export declare function newChallenge(): string;
75
92
  * type name + vocabulary namespace (match / mint)
76
93
  * @param options.collections {GrantRequestCollection[]} the collections to
77
94
  * request (WAS collection id + visibility)
95
+ * @param [options.sharedCollections] {string[]} WAS collection ids of
96
+ * wallet-owned collections to request read-and-decrypt access to; each gets a
97
+ * `urn:was:shared-collection` descriptor with {@link SHARED_ACTIONS}
78
98
  * @param [options.actions] {string[]} the RW action set (defaults to
79
99
  * `RW_ACTIONS`)
80
100
  * @returns {IVPRDetails}
81
101
  */
82
- export declare function buildAppConnectVpr({ challenge, domain, appName, credential, collections, actions }: {
102
+ export declare function buildAppConnectVpr({ challenge, domain, appName, credential, collections, sharedCollections, actions }: {
83
103
  challenge: string;
84
104
  domain: string;
85
105
  appName: string;
86
106
  credential: SeedCredentialConfig;
87
107
  collections: GrantRequestCollection[];
108
+ sharedCollections?: string[];
88
109
  actions?: string[];
89
110
  }): IVPRDetails;
90
111
  //# sourceMappingURL=loginRequest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loginRequest.d.ts","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACzE,OAAO,KAAK,EAEV,WAAW,EACZ,MAAM,yBAAyB,CAAA;AAEhC;;GAEG;AACH,eAAO,MAAM,UAAU,UAA2C,CAAA;AAElE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAA;IACV;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAClC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,MAAM,EACN,OAAO,EACP,UAAU,EACV,WAAW,EACX,OAAoB,EACrB,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,oBAAoB,CAAA;IAChC,WAAW,EAAE,sBAAsB,EAAE,CAAA;IACrC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,GAAG,WAAW,CAiCd"}
1
+ {"version":3,"file":"loginRequest.d.ts","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACzE,OAAO,KAAK,EAEV,WAAW,EACZ,MAAM,yBAAyB,CAAA;AAEhC;;GAEG;AACH,eAAO,MAAM,UAAU,UAA2C,CAAA;AAElE;;;;GAIG;AACH,eAAO,MAAM,cAAc,UAAkB,CAAA;AAE7C;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAA;IACV;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAA;CAClC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,SAAS,EACT,MAAM,EACN,OAAO,EACP,UAAU,EACV,WAAW,EACX,iBAAsB,EACtB,OAAoB,EACrB,EAAE;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,oBAAoB,CAAA;IAChC,WAAW,EAAE,sBAAsB,EAAE,CAAA;IACrC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,GAAG,WAAW,CAwCd"}
@@ -2,6 +2,12 @@
2
2
  * Default read/write actions requested on each app collection.
3
3
  */
4
4
  export const RW_ACTIONS = ['GET', 'HEAD', 'PUT', 'POST', 'DELETE'];
5
+ /**
6
+ * The actions requested on a SHARED (wallet-owned) collection: read-only, and
7
+ * not configurable. A shared collection belongs to the wallet, so an app never
8
+ * asks to write it.
9
+ */
10
+ export const SHARED_ACTIONS = ['GET', 'HEAD'];
5
11
  /**
6
12
  * A fresh nonce for a VPR challenge.
7
13
  */
@@ -30,11 +36,14 @@ export function newChallenge() {
30
36
  * type name + vocabulary namespace (match / mint)
31
37
  * @param options.collections {GrantRequestCollection[]} the collections to
32
38
  * request (WAS collection id + visibility)
39
+ * @param [options.sharedCollections] {string[]} WAS collection ids of
40
+ * wallet-owned collections to request read-and-decrypt access to; each gets a
41
+ * `urn:was:shared-collection` descriptor with {@link SHARED_ACTIONS}
33
42
  * @param [options.actions] {string[]} the RW action set (defaults to
34
43
  * `RW_ACTIONS`)
35
44
  * @returns {IVPRDetails}
36
45
  */
37
- export function buildAppConnectVpr({ challenge, domain, appName, credential, collections, actions = RW_ACTIONS }) {
46
+ export function buildAppConnectVpr({ challenge, domain, appName, credential, collections, sharedCollections = [], actions = RW_ACTIONS }) {
38
47
  const capabilityQuery = collections.map(({ id, visibility }) => ({
39
48
  referenceId: id,
40
49
  allowedAction: actions,
@@ -45,6 +54,13 @@ export function buildAppConnectVpr({ challenge, domain, appName, credential, col
45
54
  name: id
46
55
  }
47
56
  }));
57
+ for (const id of sharedCollections) {
58
+ capabilityQuery.push({
59
+ referenceId: id,
60
+ allowedAction: SHARED_ACTIONS,
61
+ invocationTarget: { type: 'urn:was:shared-collection', name: id }
62
+ });
63
+ }
48
64
  return {
49
65
  query: [
50
66
  {
@@ -1 +1 @@
1
- {"version":3,"file":"loginRequest.js","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"AAmCA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;AAmBlE;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,MAAM,CAAC,UAAU,EAAE,CAAA;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,SAAS,EACT,MAAM,EACN,OAAO,EACP,UAAU,EACV,WAAW,EACX,OAAO,GAAG,UAAU,EAQrB;IACC,MAAM,eAAe,GAAiC,WAAW,CAAC,GAAG,CACnE,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACvB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,OAAO;QACtB,gBAAgB,EAAE;YAChB,IAAI,EACF,UAAU,KAAK,QAAQ;gBACrB,CAAC,CAAC,2BAA2B;gBAC7B,CAAC,CAAC,oBAAoB;YAC1B,IAAI,EAAE,EAAE;SACT;KACF,CAAC,CACH,CAAA;IACD,OAAO;QACL,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,mBAAmB;gBACzB,eAAe,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aACrC;YACD;gBACE,IAAI,EAAE,iBAAiB;gBACvB,GAAG,EAAE;oBACH,IAAI,EAAE,OAAO;oBACb,cAAc,EAAE,UAAU,CAAC,cAAc;oBACzC,SAAS,EAAE,UAAU,CAAC,SAAS;iBAChC;gBACD,eAAe;aAChB;SACF;QACD,SAAS;QACT,MAAM;KACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"loginRequest.js","sourceRoot":"","sources":["../../src/auth/loginRequest.ts"],"names":[],"mappings":"AA8CA;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;AAmB7C;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,MAAM,CAAC,UAAU,EAAE,CAAA;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,kBAAkB,CAAC,EACjC,SAAS,EACT,MAAM,EACN,OAAO,EACP,UAAU,EACV,WAAW,EACX,iBAAiB,GAAG,EAAE,EACtB,OAAO,GAAG,UAAU,EASrB;IACC,MAAM,eAAe,GAAiC,WAAW,CAAC,GAAG,CACnE,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACvB,WAAW,EAAE,EAAE;QACf,aAAa,EAAE,OAAO;QACtB,gBAAgB,EAAE;YAChB,IAAI,EACF,UAAU,KAAK,QAAQ;gBACrB,CAAC,CAAC,2BAA2B;gBAC7B,CAAC,CAAC,oBAAoB;YAC1B,IAAI,EAAE,EAAE;SACT;KACF,CAAC,CACH,CAAA;IACD,KAAK,MAAM,EAAE,IAAI,iBAAiB,EAAE,CAAC;QACnC,eAAe,CAAC,IAAI,CAAC;YACnB,WAAW,EAAE,EAAE;YACf,aAAa,EAAE,cAAc;YAC7B,gBAAgB,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,EAAE,EAAE;SAClE,CAAC,CAAA;IACJ,CAAC;IACD,OAAO;QACL,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,mBAAmB;gBACzB,eAAe,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aACrC;YACD;gBACE,IAAI,EAAE,iBAAiB;gBACvB,GAAG,EAAE;oBACH,IAAI,EAAE,OAAO;oBACb,cAAc,EAAE,UAAU,CAAC,cAAc;oBACzC,SAAS,EAAE,UAAU,CAAC,SAAS;iBAChC;gBACD,eAAe;aAChB;SACF;QACD,SAAS;QACT,MAAM;KACP,CAAA;AACH,CAAC"}
package/dist/config.d.ts CHANGED
@@ -13,6 +13,11 @@
13
13
  * across interoperable apps). The auth layer consumes only the `id`s; this
14
14
  * config layer owns the `{ key, id }` registry the storage layer routes on.
15
15
  *
16
+ * A SHARED collection ({@link SharedCollectionConfig}) is the other direction:
17
+ * a wallet-owned, already-encrypted collection the app is granted read-and-
18
+ * decrypt access to. It has the same `{ key, id }` shape but none of the
19
+ * replication -- no RxDB collection, no writes, no local replica.
20
+ *
16
21
  * The STORE REGISTRY ({@link StoreRegistry}) is the injection seam that replaces
17
22
  * the storage-layer's former hardcoded per-entity maps: an app supplies, per
18
23
  * collection key, the four handlers the rehydrate mechanism drives (hydrate the
@@ -58,6 +63,24 @@ export interface WasCollectionConfig {
58
63
  */
59
64
  indexes?: string[];
60
65
  }
66
+ /**
67
+ * One SHARED collection: a wallet-owned, already-encrypted collection the app
68
+ * asks the wallet for read-and-decrypt access to (the
69
+ * `urn:was:shared-collection` grant). It is the mirror image of
70
+ * {@link WasCollectionConfig}: read-only, NOT replicated into RxDB, NOT written
71
+ * to, and with no local replica. Reads go straight to the server through a
72
+ * `SharedCollectionReader`.
73
+ */
74
+ export interface SharedCollectionConfig {
75
+ /**
76
+ * App-side name; the handle the app looks the reader up by.
77
+ */
78
+ key: string;
79
+ /**
80
+ * WAS collection id in the wallet's Space (e.g. `private-credentials`).
81
+ */
82
+ id: string;
83
+ }
61
84
  /**
62
85
  * Optional replication tuning; each field falls back to a documented default.
63
86
  */
@@ -113,6 +136,15 @@ export interface WasAppConfig {
113
136
  * The storage collections (logical key to WAS collection id).
114
137
  */
115
138
  collections: WasCollectionConfig[];
139
+ /**
140
+ * Wallet-owned collections this app asks to be given READ-AND-DECRYPT access
141
+ * to (the `urn:was:shared-collection` grant). Read-only by construction: they
142
+ * are never replicated into RxDB, never written to, and have no local
143
+ * replica -- reads go straight to the server through a
144
+ * `SharedCollectionReader`. A collection may be app-owned (`collections`) or
145
+ * shared, never both.
146
+ */
147
+ sharedCollections?: SharedCollectionConfig[];
116
148
  /**
117
149
  * How the router treats the pre-connection `local` state. `'local-first'`
118
150
  * renders the app immediately over the anonymous replica (connecting a wallet
@@ -230,6 +262,25 @@ export declare const DEFAULT_EXPIRY_WATCH_MS: number;
230
262
  * @returns {void}
231
263
  */
232
264
  export declare function validateCollections(collections: WasCollectionConfig[]): void;
265
+ /**
266
+ * Validates the shared-collection registry against the app-owned one,
267
+ * fail-closed. Rejects an empty `key` or `id`, a duplicate `key` or `id`, and
268
+ * any `key` or `id` that also appears in `collections`: a collection cannot be
269
+ * both app-owned (replicated, read-write, locally encrypted under the app's own
270
+ * per-collection key) and shared read-only (never replicated, decrypted through
271
+ * the wallet's epoch roster). Called by the storage layer before any replica is
272
+ * opened.
273
+ *
274
+ * @param options {object}
275
+ * @param options.collections {WasCollectionConfig[]} the app-owned registry
276
+ * @param [options.sharedCollections] {SharedCollectionConfig[]} the shared
277
+ * (read-only) registry
278
+ * @returns {void}
279
+ */
280
+ export declare function validateSharedCollections({ collections, sharedCollections }: {
281
+ collections: WasCollectionConfig[];
282
+ sharedCollections?: SharedCollectionConfig[];
283
+ }): void;
233
284
  /**
234
285
  * Resolves a localStore/RxDB collection `key` from its WAS collection `id`.
235
286
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
Binary file
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -21,9 +21,24 @@
21
21
  * app can supply a label for cosmetic continuity; it does not affect the
22
22
  * identity, keys, or any stored data.
23
23
  *
24
- * The per-collection key-agreement (KAK) derivation now lives in
25
- * `@interop/wallet-core/identity` (`deriveCollectionKeys`, along with its pinned
26
- * HKDF derivation inputs) and is re-exported here for compatibility.
24
+ * ONE KEY IDENTITY answers for encryption everywhere: the app's IDENTITY
25
+ * key-agreement key (KAK), derived here as the X25519 (Montgomery) twin of the
26
+ * did:key controller. One per app identity, and the single rule for every
27
+ * key-epoch roster entry -- a recipient is always the X25519 twin of a
28
+ * controller did:key, whether the collection is one the app provisioned or one
29
+ * the wallet SHARED with it. Both sides of a share derive it independently, so
30
+ * it never travels on the wire.
31
+ *
32
+ * Earlier versions used a second identity for app-provisioned collections: a
33
+ * per-collection KAK, HKDF-derived from the master seed under the collection id
34
+ * (`deriveCollectionKeys`, label `kak:v1:<collectionId>`). That derivation still
35
+ * lives in `@interop/wallet-core/identity` but has no caller here. Unifying cost
36
+ * the HKDF domain separation between collections -- the identity KAK now reads
37
+ * every collection the app touches. In the multi-recipient model that key only
38
+ * unwraps an epoch secret rather than being the content key, and the seed it was
39
+ * derived from is persisted in the same process anyway, so the separation bought
40
+ * less than it looked like; what it genuinely served -- handing one collection's
41
+ * key to a third party -- is what key-epoch rosters replaced.
27
42
  *
28
43
  * Not test-node-safe on React Native, but fine under Node/Vitest: the crypto
29
44
  * stack (`webkms-client`, `x25519-key-agreement-key`) runs on the standard Web
@@ -31,13 +46,7 @@
31
46
  */
32
47
  import { CapabilityAgent } from '@interop/webkms-client';
33
48
  import { ZcapClient } from '@interop/ezcap';
34
- /**
35
- * The per-collection vault-key (KAK) derivation, its result type, and its
36
- * default cosmetic handle now live in `@interop/wallet-core/identity` (moved
37
- * there verbatim, with their pinned `kak:v1:<collectionId>` HKDF derivation
38
- * inputs); re-exported here so existing imports keep working.
39
- */
40
- export { deriveCollectionKeys, DEFAULT_KAK_HANDLE, type CollectionKeys } from '@interop/wallet-core/identity';
49
+ import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
41
50
  /**
42
51
  * Default cosmetic label for the master identity agent. Local naming only (does
43
52
  * not affect key material or the derived did:key); safe to override.
@@ -45,12 +54,30 @@ export { deriveCollectionKeys, DEFAULT_KAK_HANDLE, type CollectionKeys } from '@
45
54
  export declare const DEFAULT_IDENTITY_HANDLE = "was-react";
46
55
  /**
47
56
  * The agents derived from the master seed: the app's stable did:key controller,
48
- * its signing agent, and a ZcapClient for signing storage requests later.
57
+ * its signing agent, a ZcapClient for signing storage requests later, and the
58
+ * app's IDENTITY key-agreement key (KAK) plus its resolver.
59
+ *
60
+ * The identity KAK is the X25519 twin (Montgomery form) of the did:key
61
+ * controller's Ed25519 key -- ONE key for the whole app identity, not one per
62
+ * collection. It is the recipient identity a wallet writes into the key-epoch
63
+ * roster of ANY collection this app reads: one it provisioned for the app, or
64
+ * one of the wallet's own that it SHARES with the app (the wallet derives the
65
+ * same key from the controller did:key alone, so the `id` /
66
+ * `publicKeyMultibase` match byte-for-byte and nothing has to travel on the
67
+ * wire). It is also what the local replica's EDV ciphers are built on.
49
68
  */
50
69
  export interface IdentityAgents {
51
70
  controllerDid: string;
52
71
  keyAgent: CapabilityAgent;
53
72
  zcapClient: ZcapClient;
73
+ /**
74
+ * The app's identity KAK: the X25519 twin of its did:key controller.
75
+ */
76
+ keyAgreementKey: IKeyAgreementKey;
77
+ /**
78
+ * The one-key resolver answering for {@link IdentityAgents.keyAgreementKey}.
79
+ */
80
+ keyResolver: IKeyResolver;
54
81
  }
55
82
  /**
56
83
  * Derives the master identity agents from the master seed. The did:key
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/identity/agents.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C;;;;;GAKG;AACH,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAA;AAEtC;;;GAGG;AACH,eAAO,MAAM,uBAAuB,cAAc,CAAA;AAMlD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,eAAe,CAAA;IACzB,UAAU,EAAE,UAAU,CAAA;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,EACnC,IAAI,EACJ,cAAwC,EACzC,EAAE;IACD,IAAI,EAAE,UAAU,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,cAAc,CAAC,CAa1B"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/identity/agents.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AAErC;;;GAGG;AACH,eAAO,MAAM,uBAAuB,cAAc,CAAA;AAMlD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,eAAe,CAAA;IACzB,UAAU,EAAE,UAAU,CAAA;IACtB;;OAEG;IACH,eAAe,EAAE,gBAAgB,CAAA;IACjC;;OAEG;IACH,WAAW,EAAE,YAAY,CAAA;CAC1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,EACnC,IAAI,EACJ,cAAwC,EACzC,EAAE;IACD,IAAI,EAAE,UAAU,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,GAAG,OAAO,CAAC,cAAc,CAAC,CA4B1B"}
@@ -21,9 +21,24 @@
21
21
  * app can supply a label for cosmetic continuity; it does not affect the
22
22
  * identity, keys, or any stored data.
23
23
  *
24
- * The per-collection key-agreement (KAK) derivation now lives in
25
- * `@interop/wallet-core/identity` (`deriveCollectionKeys`, along with its pinned
26
- * HKDF derivation inputs) and is re-exported here for compatibility.
24
+ * ONE KEY IDENTITY answers for encryption everywhere: the app's IDENTITY
25
+ * key-agreement key (KAK), derived here as the X25519 (Montgomery) twin of the
26
+ * did:key controller. One per app identity, and the single rule for every
27
+ * key-epoch roster entry -- a recipient is always the X25519 twin of a
28
+ * controller did:key, whether the collection is one the app provisioned or one
29
+ * the wallet SHARED with it. Both sides of a share derive it independently, so
30
+ * it never travels on the wire.
31
+ *
32
+ * Earlier versions used a second identity for app-provisioned collections: a
33
+ * per-collection KAK, HKDF-derived from the master seed under the collection id
34
+ * (`deriveCollectionKeys`, label `kak:v1:<collectionId>`). That derivation still
35
+ * lives in `@interop/wallet-core/identity` but has no caller here. Unifying cost
36
+ * the HKDF domain separation between collections -- the identity KAK now reads
37
+ * every collection the app touches. In the multi-recipient model that key only
38
+ * unwraps an epoch secret rather than being the content key, and the seed it was
39
+ * derived from is persisted in the same process anyway, so the separation bought
40
+ * less than it looked like; what it genuinely served -- handing one collection's
41
+ * key to a third party -- is what key-epoch rosters replaced.
27
42
  *
28
43
  * Not test-node-safe on React Native, but fine under Node/Vitest: the crypto
29
44
  * stack (`webkms-client`, `x25519-key-agreement-key`) runs on the standard Web
@@ -32,13 +47,8 @@
32
47
  import { CapabilityAgent } from '@interop/webkms-client';
33
48
  import { Ed25519Signature2020 } from '@interop/ed25519-signature';
34
49
  import { ZcapClient } from '@interop/ezcap';
35
- /**
36
- * The per-collection vault-key (KAK) derivation, its result type, and its
37
- * default cosmetic handle now live in `@interop/wallet-core/identity` (moved
38
- * there verbatim, with their pinned `kak:v1:<collectionId>` HKDF derivation
39
- * inputs); re-exported here so existing imports keep working.
40
- */
41
- export { deriveCollectionKeys, DEFAULT_KAK_HANDLE } from '@interop/wallet-core/identity';
50
+ import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key';
51
+ import { singleKeyResolver } from '@interop/wallet-core/identity';
42
52
  /**
43
53
  * Default cosmetic label for the master identity agent. Local naming only (does
44
54
  * not affect key material or the derived did:key); safe to override.
@@ -69,6 +79,20 @@ export async function deriveIdentity({ seed, identityHandle = DEFAULT_IDENTITY_H
69
79
  invocationSigner: signer,
70
80
  delegationSigner: signer
71
81
  });
72
- return { controllerDid: keyAgent.id, keyAgent, zcapClient };
82
+ // The identity KAK: the Ed25519-to-X25519 (Montgomery) conversion of the
83
+ // controller key pair -- the same conversion a wallet applies to the
84
+ // controller did:key when it writes this app into a shared collection's
85
+ // epoch roster.
86
+ const keyAgreementKey = X25519KeyAgreementKey2020.fromEd25519VerificationKey2020({
87
+ keyPair: keyAgent.getVerificationKeyPair()
88
+ });
89
+ const keyResolver = singleKeyResolver({ keyAgreementKey });
90
+ return {
91
+ controllerDid: keyAgent.id,
92
+ keyAgent,
93
+ zcapClient,
94
+ keyAgreementKey,
95
+ keyResolver
96
+ };
73
97
  }
74
98
  //# sourceMappingURL=agents.js.map