@interop/was-react 0.5.0 → 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.
package/README.md
CHANGED
|
@@ -379,38 +379,44 @@ The MUI entry supplies a router gate and status UI on top of this; see
|
|
|
379
379
|
|
|
380
380
|
## Login flow
|
|
381
381
|
|
|
382
|
-
Login is
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
`requesting-grants` to `verifying`):
|
|
382
|
+
Login is a single CHAPI exchange -- App Connect. The `useLogin().login()` action
|
|
383
|
+
(backed by `loginWithWallet`) runs the flow, with a `phase` string surfaced for
|
|
384
|
+
a progress line (`connecting` to `verifying`):
|
|
386
385
|
|
|
387
386
|
1. **CHAPI polyfill loads lazily.** The `credential-handler-polyfill` is loaded
|
|
388
387
|
on demand the first time a wallet request is made, not at import time.
|
|
389
|
-
2. **
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
388
|
+
2. **One popup.** A VPR carrying a `DIDAuthentication` query plus one
|
|
389
|
+
`AppConnectQuery` -- the app's display name, `credentialType`, and
|
|
390
|
+
`vocabBase`, a `capabilityQuery` entry per configured collection, and a
|
|
391
|
+
`urn:was:shared-collection` entry per shared collection -- is sent via
|
|
392
|
+
`navigator.credentials.get` (`buildAppConnectVpr`). A `null` response is a
|
|
393
|
+
user cancel (`LoginCancelledError`), not an error.
|
|
394
|
+
3. **The wallet matches or mints.** On a first run the wallet generates the
|
|
395
|
+
32-byte seed itself, self-issues the origin-bound app-key credential, and
|
|
396
|
+
stores it in its own credential store under the same consent; on a returning
|
|
397
|
+
visit it matches the stored credential by the shared `AppKeyCredential`
|
|
398
|
+
marker type, the app's `credentialType`, the requesting origin, and the
|
|
399
|
+
seed-to-subject binding. The app never mints, and there is no second popup.
|
|
400
|
+
4. **Verify the response.** `verifyLoginPresentation` checks the VP and embedded
|
|
401
|
+
proofs (purpose `authentication`, matching domain and challenge). A
|
|
402
|
+
presentation that verifies but carries no seed credential means the wallet
|
|
403
|
+
predates App Connect: the flow fails closed with `WalletUnsupportedError`
|
|
404
|
+
rather than degrading into a partial generic flow.
|
|
405
|
+
5. **Recover the seed.** `parseSeedCredential` verifies the returned credential
|
|
406
|
+
carries the `AppKeyCredential` marker type and is self-issued, origin-bound,
|
|
407
|
+
and seed-to-DID bound, then recovers the seed.
|
|
408
|
+
6. **Derive identity.** The stable `did:key` controller and its signer are
|
|
403
409
|
derived deterministically from the seed via `CapabilityAgent.fromSeed`
|
|
404
410
|
(`initAppSession` / `deriveIdentity`). The same seed yields the same identity
|
|
405
411
|
on every device.
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
412
|
+
7. **Check grants.** The delegated zcaps ride in the same presentation's
|
|
413
|
+
top-level `zcap` array. `checkGrants` asserts every zcap is controlled by the
|
|
414
|
+
app DID, shares one space on a single WAS host, covers each configured
|
|
415
|
+
collection's required actions, and is unexpired. A declined shared-collection
|
|
416
|
+
grant never fails the login. The wallet decides where the user's Space lives;
|
|
417
|
+
the sync layer derives its target from the grants. The wallet-provided
|
|
418
|
+
`appConnect: { firstRun }` member surfaces as the `{ firstRun }` the
|
|
419
|
+
`login()` promise resolves with.
|
|
414
420
|
8. **Activate.** The session (seed, grants, earliest expiry) is persisted to
|
|
415
421
|
IndexedDB, the encrypted local store is opened, the entity stores hydrate,
|
|
416
422
|
and background WAS sync starts.
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
*
|
|
32
32
|
* Earlier versions used a second identity for app-provisioned collections: a
|
|
33
33
|
* per-collection KAK, HKDF-derived from the master seed under the collection id
|
|
34
|
-
* (`deriveCollectionKeys`, label `kak:v1:<collectionId>`). That derivation
|
|
35
|
-
*
|
|
34
|
+
* (`deriveCollectionKeys`, label `kak:v1:<collectionId>`). That derivation has
|
|
35
|
+
* been removed from `@interop/wallet-core/identity`. Unifying cost
|
|
36
36
|
* the HKDF domain separation between collections -- the identity KAK now reads
|
|
37
37
|
* every collection the app touches. In the multi-recipient model that key only
|
|
38
38
|
* unwraps an epoch secret rather than being the content key, and the seed it was
|
package/dist/identity/agents.js
CHANGED
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
*
|
|
32
32
|
* Earlier versions used a second identity for app-provisioned collections: a
|
|
33
33
|
* per-collection KAK, HKDF-derived from the master seed under the collection id
|
|
34
|
-
* (`deriveCollectionKeys`, label `kak:v1:<collectionId>`). That derivation
|
|
35
|
-
*
|
|
34
|
+
* (`deriveCollectionKeys`, label `kak:v1:<collectionId>`). That derivation has
|
|
35
|
+
* been removed from `@interop/wallet-core/identity`. Unifying cost
|
|
36
36
|
* the HKDF domain separation between collections -- the identity KAK now reads
|
|
37
37
|
* every collection the app touches. In the multi-recipient model that key only
|
|
38
38
|
* unwraps an epoch secret rather than being the content key, and the seed it was
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentLoader.d.ts","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"documentLoader.d.ts","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAeF;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
|
|
@@ -3,13 +3,28 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* The app's one JSON-LD document loader: static security contexts plus did:key
|
|
6
|
-
* / did:web
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* / did:web / did:webvh resolution. The resolver starts from
|
|
7
|
+
* `@interop/security-document-loader`'s default did:key + did:web driver set
|
|
8
|
+
* and adds the `@interop/did-method-webvh` driver, so a wallet may present its
|
|
9
|
+
* VP holder as a did:webvh (signed with a `<did:webvh>#<key>` verification
|
|
10
|
+
* method) and verification still resolves it. webvh resolution stays VERIFIED
|
|
11
|
+
* resolution: the driver's default history-log verifier (hash chain + entry
|
|
12
|
+
* proofs) is active, so a tampered `did.jsonl` fails closed. DIDs on loopback
|
|
13
|
+
* hosts (a local dev server) resolve over plain http; both the did:web
|
|
14
|
+
* resolver and the webvh driver's `did.jsonl` fetch handle that natively, so
|
|
15
|
+
* no dev shim is needed here.
|
|
10
16
|
*/
|
|
11
|
-
import {
|
|
12
|
-
|
|
17
|
+
import { createDidWebvhDriver } from '@interop/did-method-webvh/driver';
|
|
18
|
+
import { createDefaultDidResolver, securityLoader } from '@interop/security-document-loader';
|
|
19
|
+
const didResolver = createDefaultDidResolver();
|
|
20
|
+
// The webvh driver is resolution-only (`{ method, get, resolveDID }`) by
|
|
21
|
+
// design; did-io's DidMethodDriver type also demands the key-generation
|
|
22
|
+
// surface (generate, fromKeyPair, ...), which resolution never calls.
|
|
23
|
+
didResolver.use(createDidWebvhDriver());
|
|
24
|
+
const baseLoader = securityLoader({
|
|
25
|
+
fetchRemoteContexts: true,
|
|
26
|
+
didResolver
|
|
27
|
+
}).build();
|
|
13
28
|
/**
|
|
14
29
|
* Builds the JSON-LD document loader handed to `@interop/vc` issuance and
|
|
15
30
|
* verifier-core verification.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentLoader.js","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"documentLoader.js","sourceRoot":"","sources":["../../src/identity/documentLoader.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AACvE,OAAO,EACL,wBAAwB,EACxB,cAAc,EACf,MAAM,mCAAmC,CAAA;AAW1C,MAAM,WAAW,GAAG,wBAAwB,EAAE,CAAA;AAC9C,yEAAyE;AACzE,wEAAwE;AACxE,sEAAsE;AACtE,WAAW,CAAC,GAAG,CACb,oBAAoB,EAAsD,CAC3E,CAAA;AAED,MAAM,UAAU,GAAG,cAAc,CAAC;IAChC,mBAAmB,EAAE,IAAI;IACzB,WAAW;CACZ,CAAC,CAAC,KAAK,EAAE,CAAA;AAEV;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,UAA4B,CAAA;AACrC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/was-react",
|
|
3
3
|
"description": "React library for building 'Bring Your Own Everything' (BYOE) apps on Wallet Attached Storage: DID Auth login via CHAPI wallet, local-first encrypted storage, and background sync to a WAS server.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "pnpm run clear && tsc",
|
|
@@ -47,13 +47,14 @@
|
|
|
47
47
|
"sideEffects": false,
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@interop/data-integrity-core": "^8.4.0",
|
|
50
|
+
"@interop/did-method-webvh": "^5.0.0",
|
|
50
51
|
"@interop/ed25519-signature": "^7.1.4",
|
|
51
52
|
"@interop/ezcap": "^7.4.1",
|
|
52
|
-
"@interop/security-document-loader": "^9.
|
|
53
|
+
"@interop/security-document-loader": "^9.5.0",
|
|
53
54
|
"@interop/vc": "^11.0.6",
|
|
54
55
|
"@interop/verifier-core": "^3.5.0",
|
|
55
56
|
"@interop/wallet-core": "^0.5.0",
|
|
56
|
-
"@interop/was-client": "^0.
|
|
57
|
+
"@interop/was-client": "^0.22.0",
|
|
57
58
|
"@interop/webkms-client": "^14.7.1",
|
|
58
59
|
"@interop/x25519-key-agreement-key": "^5.2.1",
|
|
59
60
|
"@scure/base": "^2.2.0",
|