@interop/wallet-core 0.1.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 (55) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +83 -0
  3. package/dist/index.d.ts +15 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +15 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/space/activity.d.ts +175 -0
  8. package/dist/space/activity.d.ts.map +1 -0
  9. package/dist/space/activity.js +209 -0
  10. package/dist/space/activity.js.map +1 -0
  11. package/dist/space/collections.d.ts +65 -0
  12. package/dist/space/collections.d.ts.map +1 -0
  13. package/dist/space/collections.js +65 -0
  14. package/dist/space/collections.js.map +1 -0
  15. package/dist/space/errors.d.ts +14 -0
  16. package/dist/space/errors.d.ts.map +1 -0
  17. package/dist/space/errors.js +18 -0
  18. package/dist/space/errors.js.map +1 -0
  19. package/dist/space/index.d.ts +26 -0
  20. package/dist/space/index.d.ts.map +1 -0
  21. package/dist/space/index.js +23 -0
  22. package/dist/space/index.js.map +1 -0
  23. package/dist/space/publicLink.d.ts +17 -0
  24. package/dist/space/publicLink.d.ts.map +1 -0
  25. package/dist/space/publicLink.js +27 -0
  26. package/dist/space/publicLink.js.map +1 -0
  27. package/dist/space/wasLink.d.ts +37 -0
  28. package/dist/space/wasLink.d.ts.map +1 -0
  29. package/dist/space/wasLink.js +123 -0
  30. package/dist/space/wasLink.js.map +1 -0
  31. package/dist/sync/collections.d.ts +61 -0
  32. package/dist/sync/collections.d.ts.map +1 -0
  33. package/dist/sync/collections.js +2 -0
  34. package/dist/sync/collections.js.map +1 -0
  35. package/dist/sync/engine.d.ts +112 -0
  36. package/dist/sync/engine.d.ts.map +1 -0
  37. package/dist/sync/engine.js +188 -0
  38. package/dist/sync/engine.js.map +1 -0
  39. package/dist/sync/index.d.ts +33 -0
  40. package/dist/sync/index.d.ts.map +1 -0
  41. package/dist/sync/index.js +29 -0
  42. package/dist/sync/index.js.map +1 -0
  43. package/dist/sync/pull.d.ts +68 -0
  44. package/dist/sync/pull.d.ts.map +1 -0
  45. package/dist/sync/pull.js +92 -0
  46. package/dist/sync/pull.js.map +1 -0
  47. package/dist/sync/push.d.ts +55 -0
  48. package/dist/sync/push.d.ts.map +1 -0
  49. package/dist/sync/push.js +191 -0
  50. package/dist/sync/push.js.map +1 -0
  51. package/dist/sync/types.d.ts +123 -0
  52. package/dist/sync/types.d.ts.map +1 -0
  53. package/dist/sync/types.js +25 -0
  54. package/dist/sync/types.js.map +1 -0
  55. package/package.json +94 -0
package/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Interop Alliance
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Wallet Core _(@interop/wallet-core)_
2
+
3
+ [![Node.js CI](https://github.com/interop-alliance/wallet-core/workflows/CI/badge.svg)](https://github.com/interop-alliance/wallet-core/actions?query=workflow%3A%22CI%22)
4
+ [![NPM Version](https://img.shields.io/npm/v/@interop/wallet-core.svg)](https://npm.im/@interop/wallet-core)
5
+
6
+ > Shared wallet-domain logic (WAS sync engine core and wallet Space layout
7
+ > contracts) for Interop wallet apps.
8
+
9
+ ## Table of Contents
10
+
11
+ - [Background](#background)
12
+ - [Install](#install)
13
+ - [Usage](#usage)
14
+ - [Contribute](#contribute)
15
+ - [License](#license)
16
+
17
+ ## Background
18
+
19
+ `@interop/wallet-core` is the shared, correctness-critical code two WAS-enabled
20
+ wallet apps (a React Native mobile wallet and a browser wallet) hold in common:
21
+ the cross-replica byte-compatibility surface both must agree on to converge on
22
+ identical bytes. It is isomorphic (browser, Node.js, React Native) and has no
23
+ UI, storage, or crypto-key dependencies -- every side effect is injected.
24
+
25
+ Two subpaths:
26
+
27
+ - **`@interop/wallet-core/sync`** -- the Wallet Attached Storage (WAS)
28
+ replication engine core: the `SyncEngine` orchestration (single-flight,
29
+ migrate-once, backoff), the `runPull` / `runPush` algorithms, the replica-side
30
+ `SyncStore` seam, and the generic `SyncedCollectionSpec` shape. The wire
31
+ contract and port (`WasSyncPort`, `WireDoc`, `DocCipher`, ...) are re-exported
32
+ from [`@interop/was-client`](https://npm.im/@interop/was-client) so an engine
33
+ consumer imports one package.
34
+
35
+ - **`@interop/wallet-core/space`** -- the wallet Space layout contract: the
36
+ shared collection ids and descriptive specs (`private-credentials`,
37
+ `public-credentials`, `wallet-activity`), the `wallet-activity` wire shape
38
+ with its pure `addHistory*` payload builders, the `publicCredentialUrl`
39
+ derivation, and the `was-link` QR hand-off contract. Contacts collection specs
40
+ live in [`@interop/social-core`](https://npm.im/@interop/social-core).
41
+
42
+ ## Install
43
+
44
+ - Node.js 24+ is recommended.
45
+
46
+ ```
47
+ pnpm install @interop/wallet-core
48
+ ```
49
+
50
+ ### Development
51
+
52
+ ```
53
+ git clone https://github.com/interop-alliance/wallet-core.git
54
+ cd wallet-core
55
+ pnpm install
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ ```ts
61
+ import { SyncEngine, runPull, runPush } from '@interop/wallet-core/sync'
62
+ import {
63
+ PRIVATE_CREDENTIALS_COLLECTION,
64
+ publicCredentialUrl,
65
+ buildWasLinkPayload,
66
+ parseWasLinkPayload,
67
+ addHistoryCredentialCreated
68
+ } from '@interop/wallet-core/space'
69
+ ```
70
+
71
+ Both subpaths are re-exported from the package root as well.
72
+
73
+ ## Contribute
74
+
75
+ PRs accepted. See [CONTRIBUTING.md](CONTRIBUTING.md) for editor setup (Prettier,
76
+ ESLint, and EditorConfig) and how it maps to CI.
77
+
78
+ If editing the Readme, please conform to the
79
+ [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
80
+
81
+ ## License
82
+
83
+ [MIT License](LICENSE.md) © 2026 Interop Alliance.
@@ -0,0 +1,15 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * `@interop/wallet-core` -- shared wallet-domain logic for Interop wallet apps.
6
+ * The two subpaths are canonical and can be imported directly:
7
+ *
8
+ * - `@interop/wallet-core/sync` -- the WAS replication engine core.
9
+ * - `@interop/wallet-core/space` -- the wallet Space layout contract.
10
+ *
11
+ * This root re-exports both for convenience.
12
+ */
13
+ export * from './sync/index.js';
14
+ export * from './space/index.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * `@interop/wallet-core` -- shared wallet-domain logic for Interop wallet apps.
6
+ * The two subpaths are canonical and can be imported directly:
7
+ *
8
+ * - `@interop/wallet-core/sync` -- the WAS replication engine core.
9
+ * - `@interop/wallet-core/space` -- the wallet Space layout contract.
10
+ *
11
+ * This root re-exports both for convenience.
12
+ */
13
+ export * from './sync/index.js';
14
+ export * from './space/index.js';
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;GAQG;AACH,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,175 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `wallet-activity` wire shape and the pure payload builders for it.
6
+ *
7
+ * {@link WalletActivity} is the decrypted body of one `wallet-activity`
8
+ * document: an ActivityStreams-shaped record (a typed action carrying a
9
+ * human-readable summary and a creation timestamp). Both wallet replicas read
10
+ * and write this exact shape, so each reads the other's entries. Every field is
11
+ * optional because a payload arrives from the storage server and is not
12
+ * schema-validated on read.
13
+ *
14
+ * The builders are pure: each returns the activity payload object only -- no
15
+ * storage, no port calls. `id` and `created` are injectable (a caller that wants
16
+ * a specific resource id or timestamp passes them); otherwise `id` defaults to
17
+ * `crypto.randomUUID()` and `created` to `new Date().toISOString()`. The
18
+ * `type` strings and `summary` phrasings are byte-significant: two replicas that
19
+ * build the same activity must produce the same `type` / `summary`, so these are
20
+ * kept verbatim.
21
+ */
22
+ /**
23
+ * The decrypted body of one `wallet-activity` document. Reconciles the web
24
+ * wallet's `WalletActivity` interface and the mobile wallet's
25
+ * `WalletActivityPayload`, which are the same shape.
26
+ */
27
+ export interface WalletActivity {
28
+ id?: string;
29
+ type?: string[];
30
+ summary?: string;
31
+ actor?: unknown;
32
+ object?: unknown;
33
+ created?: string;
34
+ }
35
+ /** The activity `type` strings the wallet uses, verbatim on the wire. */
36
+ export declare const ACTIVITY_TYPE: {
37
+ readonly Create: "Create";
38
+ readonly Delete: "Delete";
39
+ readonly Share: "Share";
40
+ readonly Unshare: "Unshare";
41
+ readonly Login: "Login";
42
+ readonly Revoke: "Revoke";
43
+ readonly CollectionShare: "CollectionShare";
44
+ readonly CollectionUnshare: "CollectionUnshare";
45
+ };
46
+ /** A minimal actor descriptor; the wallet records the user's email. */
47
+ type Actor = {
48
+ email?: string;
49
+ id?: string;
50
+ };
51
+ /**
52
+ * The Create activity for a freshly generated bootstrap `did:key` DID.
53
+ *
54
+ * @param options {object}
55
+ * @param options.user {Actor}
56
+ * @param [options.id] {string}
57
+ * @param [options.created] {string}
58
+ * @returns {WalletActivity}
59
+ */
60
+ export declare function addHistoryNewAccount({ user, id, created }: {
61
+ user: Actor;
62
+ id?: string;
63
+ created?: string;
64
+ }): WalletActivity;
65
+ /**
66
+ * The Create activity for the wallet's storage collections (and, when a remote
67
+ * replica is configured, the remote Space). `object` -- the created Space /
68
+ * Collection descriptors -- is supplied by the caller (it comes from the app's
69
+ * storage layer); `remote` selects the summary phrasing.
70
+ *
71
+ * @param options {object}
72
+ * @param options.actor {unknown} recorded as the activity actor
73
+ * @param options.object {unknown} the created Space / Collection descriptors
74
+ * @param [options.remote] {boolean} whether a remote Space was created
75
+ * @param [options.id] {string}
76
+ * @param [options.created] {string}
77
+ * @returns {WalletActivity}
78
+ */
79
+ export declare function addHistorySpaceCreated({ actor, object, remote, id, created }: {
80
+ actor: unknown;
81
+ object: unknown;
82
+ remote?: boolean;
83
+ id?: string;
84
+ created?: string;
85
+ }): WalletActivity;
86
+ /** The Create activity for a credential. */
87
+ export declare function addHistoryCredentialCreated({ cid, user, id, created }: {
88
+ cid: string;
89
+ user: Actor;
90
+ id?: string;
91
+ created?: string;
92
+ }): WalletActivity;
93
+ /** The Delete activity for a credential. */
94
+ export declare function addHistoryCredentialDeleted({ cid, user, id, created }: {
95
+ cid: string;
96
+ user: Actor;
97
+ id?: string;
98
+ created?: string;
99
+ }): WalletActivity;
100
+ /** The Share activity for a credential (a public link created). */
101
+ export declare function addHistoryCredentialShared({ cid, user, id, created }: {
102
+ cid: string;
103
+ user: Actor;
104
+ id?: string;
105
+ created?: string;
106
+ }): WalletActivity;
107
+ /** The Unshare activity for a credential (a public link revoked). */
108
+ export declare function addHistoryCredentialUnshared({ cid, user, id, created }: {
109
+ cid: string;
110
+ user: Actor;
111
+ id?: string;
112
+ created?: string;
113
+ }): WalletActivity;
114
+ /** One capability grant recorded on a Login activity. `zcap` is kept verbatim. */
115
+ export interface ActivityGrant {
116
+ id: string;
117
+ target: string;
118
+ allowedActions: string[];
119
+ expires: string;
120
+ zcap?: unknown;
121
+ }
122
+ /**
123
+ * The Login activity: the user logged in to a relying party (or connected an
124
+ * app) via "Login with Wallet", granting the listed capabilities. The recorded
125
+ * zcap ids are the hook for a later revocation UI.
126
+ *
127
+ * @param options {object}
128
+ * @param options.user {Actor}
129
+ * @param options.origin {string} the relying party's origin
130
+ * @param options.grants {ActivityGrant[]}
131
+ * @param [options.appConnect] {{ name: string; firstRun: boolean }} set for an
132
+ * App Connect login: the app's display name and whether the app key was minted
133
+ * on this connect (first run) or matched (returning)
134
+ * @param [options.id] {string}
135
+ * @param [options.created] {string}
136
+ * @returns {WalletActivity}
137
+ */
138
+ export declare function addHistoryLogin({ user, origin, grants, appConnect, id, created }: {
139
+ user: Actor;
140
+ origin: string;
141
+ grants: ActivityGrant[];
142
+ appConnect?: {
143
+ name: string;
144
+ firstRun: boolean;
145
+ };
146
+ id?: string;
147
+ created?: string;
148
+ }): WalletActivity;
149
+ /**
150
+ * The Revoke activity: the user revoked a connected app's access, retiring its
151
+ * app-key credential and its storage grants.
152
+ *
153
+ * @param options {object}
154
+ * @param options.user {Actor}
155
+ * @param options.origin {string} the connected app's origin
156
+ * @param options.name {string} the connected app's display name
157
+ * @param [options.cid] {string} the retired app-key credential's cid
158
+ * @param [options.revoked] {number} how many storage grants were revoked
159
+ * @param [options.skipped] {number} how many grants needed no revocation
160
+ * @param [options.id] {string}
161
+ * @param [options.created] {string}
162
+ * @returns {WalletActivity}
163
+ */
164
+ export declare function addHistoryAppRevoke({ user, origin, name, cid, revoked, skipped, id, created }: {
165
+ user: Actor;
166
+ origin: string;
167
+ name: string;
168
+ cid?: string;
169
+ revoked?: number;
170
+ skipped?: number;
171
+ id?: string;
172
+ created?: string;
173
+ }): WalletActivity;
174
+ export {};
175
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../src/space/activity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,209 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `wallet-activity` wire shape and the pure payload builders for it.
6
+ *
7
+ * {@link WalletActivity} is the decrypted body of one `wallet-activity`
8
+ * document: an ActivityStreams-shaped record (a typed action carrying a
9
+ * human-readable summary and a creation timestamp). Both wallet replicas read
10
+ * and write this exact shape, so each reads the other's entries. Every field is
11
+ * optional because a payload arrives from the storage server and is not
12
+ * schema-validated on read.
13
+ *
14
+ * The builders are pure: each returns the activity payload object only -- no
15
+ * storage, no port calls. `id` and `created` are injectable (a caller that wants
16
+ * a specific resource id or timestamp passes them); otherwise `id` defaults to
17
+ * `crypto.randomUUID()` and `created` to `new Date().toISOString()`. The
18
+ * `type` strings and `summary` phrasings are byte-significant: two replicas that
19
+ * build the same activity must produce the same `type` / `summary`, so these are
20
+ * kept verbatim.
21
+ */
22
+ /** The activity `type` strings the wallet uses, verbatim on the wire. */
23
+ export const ACTIVITY_TYPE = {
24
+ Create: 'Create',
25
+ Delete: 'Delete',
26
+ Share: 'Share',
27
+ Unshare: 'Unshare',
28
+ Login: 'Login',
29
+ Revoke: 'Revoke',
30
+ CollectionShare: 'CollectionShare',
31
+ CollectionUnshare: 'CollectionUnshare'
32
+ };
33
+ /** Fills in the id / created defaults shared by every builder. */
34
+ function stamp(id, created) {
35
+ return {
36
+ id: id ?? crypto.randomUUID(),
37
+ created: created ?? new Date().toISOString()
38
+ };
39
+ }
40
+ /**
41
+ * The Create activity for a freshly generated bootstrap `did:key` DID.
42
+ *
43
+ * @param options {object}
44
+ * @param options.user {Actor}
45
+ * @param [options.id] {string}
46
+ * @param [options.created] {string}
47
+ * @returns {WalletActivity}
48
+ */
49
+ export function addHistoryNewAccount({ user, id, created }) {
50
+ const stamped = stamp(id, created);
51
+ return {
52
+ id: stamped.id,
53
+ type: [ACTIVITY_TYPE.Create],
54
+ summary: 'Account Sign Up. did:key DID generated.',
55
+ actor: { email: user.email },
56
+ object: user.id,
57
+ created: stamped.created
58
+ };
59
+ }
60
+ /**
61
+ * The Create activity for the wallet's storage collections (and, when a remote
62
+ * replica is configured, the remote Space). `object` -- the created Space /
63
+ * Collection descriptors -- is supplied by the caller (it comes from the app's
64
+ * storage layer); `remote` selects the summary phrasing.
65
+ *
66
+ * @param options {object}
67
+ * @param options.actor {unknown} recorded as the activity actor
68
+ * @param options.object {unknown} the created Space / Collection descriptors
69
+ * @param [options.remote] {boolean} whether a remote Space was created
70
+ * @param [options.id] {string}
71
+ * @param [options.created] {string}
72
+ * @returns {WalletActivity}
73
+ */
74
+ export function addHistorySpaceCreated({ actor, object, remote, id, created }) {
75
+ const stamped = stamp(id, created);
76
+ return {
77
+ id: stamped.id,
78
+ type: [ACTIVITY_TYPE.Create],
79
+ summary: remote
80
+ ? 'Account space created on remote storage server, collections initialized.'
81
+ : 'Wallet collections initialized in local storage.',
82
+ actor,
83
+ object,
84
+ created: stamped.created
85
+ };
86
+ }
87
+ /**
88
+ * The shared shape behind the four credential builders, which differ only in the
89
+ * activity type and the summary verb.
90
+ */
91
+ function credentialActivity({ cid, user, type, verb, id, created }) {
92
+ const stamped = stamp(id, created);
93
+ return {
94
+ id: stamped.id,
95
+ type: [type],
96
+ summary: `Credential ${verb}: ${cid}`,
97
+ actor: { email: user.email },
98
+ object: cid,
99
+ created: stamped.created
100
+ };
101
+ }
102
+ /** The Create activity for a credential. */
103
+ export function addHistoryCredentialCreated({ cid, user, id, created }) {
104
+ return credentialActivity({
105
+ cid,
106
+ user,
107
+ type: ACTIVITY_TYPE.Create,
108
+ verb: 'created',
109
+ id,
110
+ created
111
+ });
112
+ }
113
+ /** The Delete activity for a credential. */
114
+ export function addHistoryCredentialDeleted({ cid, user, id, created }) {
115
+ return credentialActivity({
116
+ cid,
117
+ user,
118
+ type: ACTIVITY_TYPE.Delete,
119
+ verb: 'deleted',
120
+ id,
121
+ created
122
+ });
123
+ }
124
+ /** The Share activity for a credential (a public link created). */
125
+ export function addHistoryCredentialShared({ cid, user, id, created }) {
126
+ return credentialActivity({
127
+ cid,
128
+ user,
129
+ type: ACTIVITY_TYPE.Share,
130
+ verb: 'shared',
131
+ id,
132
+ created
133
+ });
134
+ }
135
+ /** The Unshare activity for a credential (a public link revoked). */
136
+ export function addHistoryCredentialUnshared({ cid, user, id, created }) {
137
+ return credentialActivity({
138
+ cid,
139
+ user,
140
+ type: ACTIVITY_TYPE.Unshare,
141
+ verb: 'unshared',
142
+ id,
143
+ created
144
+ });
145
+ }
146
+ /**
147
+ * The Login activity: the user logged in to a relying party (or connected an
148
+ * app) via "Login with Wallet", granting the listed capabilities. The recorded
149
+ * zcap ids are the hook for a later revocation UI.
150
+ *
151
+ * @param options {object}
152
+ * @param options.user {Actor}
153
+ * @param options.origin {string} the relying party's origin
154
+ * @param options.grants {ActivityGrant[]}
155
+ * @param [options.appConnect] {{ name: string; firstRun: boolean }} set for an
156
+ * App Connect login: the app's display name and whether the app key was minted
157
+ * on this connect (first run) or matched (returning)
158
+ * @param [options.id] {string}
159
+ * @param [options.created] {string}
160
+ * @returns {WalletActivity}
161
+ */
162
+ export function addHistoryLogin({ user, origin, grants, appConnect, id, created }) {
163
+ const stamped = stamp(id, created);
164
+ const summary = appConnect
165
+ ? `Connected ${appConnect.name} (${origin}) to wallet` +
166
+ `${appConnect.firstRun ? ', minting a new app key' : ''}.`
167
+ : `Logged in to ${origin} with wallet.`;
168
+ return {
169
+ id: stamped.id,
170
+ type: [ACTIVITY_TYPE.Login],
171
+ summary,
172
+ actor: { email: user.email },
173
+ object: appConnect
174
+ ? { origin, zcaps: grants, appConnect }
175
+ : { origin, zcaps: grants },
176
+ created: stamped.created
177
+ };
178
+ }
179
+ /**
180
+ * The Revoke activity: the user revoked a connected app's access, retiring its
181
+ * app-key credential and its storage grants.
182
+ *
183
+ * @param options {object}
184
+ * @param options.user {Actor}
185
+ * @param options.origin {string} the connected app's origin
186
+ * @param options.name {string} the connected app's display name
187
+ * @param [options.cid] {string} the retired app-key credential's cid
188
+ * @param [options.revoked] {number} how many storage grants were revoked
189
+ * @param [options.skipped] {number} how many grants needed no revocation
190
+ * @param [options.id] {string}
191
+ * @param [options.created] {string}
192
+ * @returns {WalletActivity}
193
+ */
194
+ export function addHistoryAppRevoke({ user, origin, name, cid, revoked, skipped, id, created }) {
195
+ const stamped = stamp(id, created);
196
+ const summary = typeof revoked === 'number'
197
+ ? `Revoked ${name} (${origin}) app access: ${revoked} grant(s) ` +
198
+ `revoked${skipped ? `, ${skipped} skipped` : ''}.`
199
+ : `Revoked ${name} (${origin}) app access.`;
200
+ return {
201
+ id: stamped.id,
202
+ type: [ACTIVITY_TYPE.Revoke],
203
+ summary,
204
+ actor: { email: user.email },
205
+ object: { origin, appConnect: { name }, cid, revoked, skipped },
206
+ created: stamped.created
207
+ };
208
+ }
209
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/space/activity.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;GAiBG;AAgBH,yEAAyE;AACzE,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,eAAe,EAAE,iBAAiB;IAClC,iBAAiB,EAAE,mBAAmB;CAC9B,CAAA;AAKV,kEAAkE;AAClE,SAAS,KAAK,CAAC,EAAW,EAAE,OAAgB;IAC1C,OAAO;QACL,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE;QAC7B,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAC7C,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,IAAI,EACJ,EAAE,EACF,OAAO,EAKR;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAClC,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;QAC5B,OAAO,EAAE,yCAAyC;QAClD,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QAC5B,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,KAAK,EACL,MAAM,EACN,MAAM,EACN,EAAE,EACF,OAAO,EAOR;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAClC,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;QAC5B,OAAO,EAAE,MAAM;YACb,CAAC,CAAC,0EAA0E;YAC5E,CAAC,CAAC,kDAAkD;QACtD,KAAK;QACL,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,EAC1B,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,EAAE,EACF,OAAO,EAQR;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAClC,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,cAAc,IAAI,KAAK,GAAG,EAAE;QACrC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QAC5B,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAA;AACH,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,2BAA2B,CAAC,EAC1C,GAAG,EACH,IAAI,EACJ,EAAE,EACF,OAAO,EAMR;IACC,OAAO,kBAAkB,CAAC;QACxB,GAAG;QACH,IAAI;QACJ,IAAI,EAAE,aAAa,CAAC,MAAM;QAC1B,IAAI,EAAE,SAAS;QACf,EAAE;QACF,OAAO;KACR,CAAC,CAAA;AACJ,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,2BAA2B,CAAC,EAC1C,GAAG,EACH,IAAI,EACJ,EAAE,EACF,OAAO,EAMR;IACC,OAAO,kBAAkB,CAAC;QACxB,GAAG;QACH,IAAI;QACJ,IAAI,EAAE,aAAa,CAAC,MAAM;QAC1B,IAAI,EAAE,SAAS;QACf,EAAE;QACF,OAAO;KACR,CAAC,CAAA;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,0BAA0B,CAAC,EACzC,GAAG,EACH,IAAI,EACJ,EAAE,EACF,OAAO,EAMR;IACC,OAAO,kBAAkB,CAAC;QACxB,GAAG;QACH,IAAI;QACJ,IAAI,EAAE,aAAa,CAAC,KAAK;QACzB,IAAI,EAAE,QAAQ;QACd,EAAE;QACF,OAAO;KACR,CAAC,CAAA;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,4BAA4B,CAAC,EAC3C,GAAG,EACH,IAAI,EACJ,EAAE,EACF,OAAO,EAMR;IACC,OAAO,kBAAkB,CAAC;QACxB,GAAG;QACH,IAAI;QACJ,IAAI,EAAE,aAAa,CAAC,OAAO;QAC3B,IAAI,EAAE,UAAU;QAChB,EAAE;QACF,OAAO;KACR,CAAC,CAAA;AACJ,CAAC;AAWD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,IAAI,EACJ,MAAM,EACN,MAAM,EACN,UAAU,EACV,EAAE,EACF,OAAO,EAQR;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAClC,MAAM,OAAO,GAAG,UAAU;QACxB,CAAC,CAAC,aAAa,UAAU,CAAC,IAAI,KAAK,MAAM,aAAa;YACpD,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,GAAG;QAC5D,CAAC,CAAC,gBAAgB,MAAM,eAAe,CAAA;IACzC,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC;QAC3B,OAAO;QACP,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QAC5B,MAAM,EAAE,UAAU;YAChB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE;YACvC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;QAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,GAAG,EACH,OAAO,EACP,OAAO,EACP,EAAE,EACF,OAAO,EAUR;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAClC,MAAM,OAAO,GACX,OAAO,OAAO,KAAK,QAAQ;QACzB,CAAC,CAAC,WAAW,IAAI,KAAK,MAAM,iBAAiB,OAAO,YAAY;YAC9D,UAAU,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG;QACpD,CAAC,CAAC,WAAW,IAAI,KAAK,MAAM,eAAe,CAAA;IAC/C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC;QAC5B,OAAO;QACP,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;QAC5B,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;QAC/D,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAA;AACH,CAAC"}
@@ -0,0 +1,65 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The shared wallet Space layout: the collection ids and descriptive specs both
6
+ * wallet replicas provision, so a credential written by one is found and read by
7
+ * the other. Both replicas MUST agree on every field here -- `collectionId`
8
+ * decides where a document lands on the server, `idDerivation` and `mutable`
9
+ * decide whether it is overwritten in place or only appended, and `encryption` /
10
+ * `isPublic` decide how it is stored and who can read it. A disagreement splits
11
+ * the feed into separate or incompatibly-shaped collections that never converge.
12
+ *
13
+ * The contacts collections (`contacts`, `contacts-history`) are NOT declared
14
+ * here: their ids and specs live in `@interop/social-core`
15
+ * (`CONTACTS_COLLECTION_SPEC` / `CONTACTS_HISTORY_COLLECTION_SPEC`), which apps
16
+ * import directly. The field vocabulary below mirrors that spec.
17
+ */
18
+ /** The immutable, content-addressed, EDV-encrypted credential replica. */
19
+ export declare const PRIVATE_CREDENTIALS_COLLECTION = "private-credentials";
20
+ /** The plaintext, world-readable copies of publicly shared credentials. */
21
+ export declare const PUBLIC_CREDENTIALS_COLLECTION = "public-credentials";
22
+ /** The append-only, EDV-encrypted wallet activity log. */
23
+ export declare const WALLET_ACTIVITY_COLLECTION = "wallet-activity";
24
+ /**
25
+ * A declarative descriptor of a synced wallet Space collection, aligned with
26
+ * `@interop/social-core`'s `CONTACTS_COLLECTION_SPEC` vocabulary and extended
27
+ * with the storage attributes the wallet Space needs:
28
+ *
29
+ * - `idDerivation` -- `'content'` for an append-only, content-addressed log (the
30
+ * id IS the hash of the stored body) or `'random'` for a mutable head (a
31
+ * stable id whose body is overwritten).
32
+ * - `mutable` -- whether a document is overwritten in place (`true`) or only
33
+ * ever appended (`false`).
34
+ * - `encryption` -- `'edv'` stores each document as an EDV envelope; `'plaintext'`
35
+ * stores it verbatim.
36
+ * - `isPublic` -- whether the collection is granted collection-level world read
37
+ * on the server.
38
+ */
39
+ export interface SpaceCollectionSpec {
40
+ collectionId: string;
41
+ idDerivation: 'content' | 'random';
42
+ mutable: boolean;
43
+ encryption: 'edv' | 'plaintext';
44
+ isPublic: boolean;
45
+ }
46
+ /**
47
+ * The immutable credential replica: each credential stored as an EDV envelope,
48
+ * addressed by the envelope's content hash, never overwritten, never public.
49
+ */
50
+ export declare const PRIVATE_CREDENTIALS_COLLECTION_SPEC: SpaceCollectionSpec;
51
+ /**
52
+ * The plaintext, world-readable copies of shared credentials, keyed by the
53
+ * credential's content cid (the same id every replica mints, so a share
54
+ * converges), granted collection-level world read on the server.
55
+ */
56
+ export declare const PUBLIC_CREDENTIALS_COLLECTION_SPEC: SpaceCollectionSpec;
57
+ /**
58
+ * The append-only activity log: each entry stored as an EDV envelope, addressed
59
+ * by content hash, never overwritten, never public. Shared with the web wallet's
60
+ * `wallet-activity` collection, so each replica reads the other's entries.
61
+ */
62
+ export declare const WALLET_ACTIVITY_COLLECTION_SPEC: SpaceCollectionSpec;
63
+ /** The wallet Space's own (non-contacts) collection specs, in provision order. */
64
+ export declare const WALLET_SPACE_COLLECTION_SPECS: SpaceCollectionSpec[];
65
+ //# sourceMappingURL=collections.d.ts.map
@@ -0,0 +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"}