@interop/wallet-core 0.93.0 → 0.95.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 (100) hide show
  1. package/README.md +21 -20
  2. package/dist/clientAnnex/mend.js +4 -1
  3. package/dist/clientAnnex/mend.js.map +1 -1
  4. package/dist/clients/index.d.ts +3 -2
  5. package/dist/clients/index.d.ts.map +1 -1
  6. package/dist/clients/index.js +3 -2
  7. package/dist/clients/index.js.map +1 -1
  8. package/dist/clients/listing.d.ts +19 -12
  9. package/dist/clients/listing.d.ts.map +1 -1
  10. package/dist/clients/listing.js +69 -22
  11. package/dist/clients/listing.js.map +1 -1
  12. package/dist/connections/didKey.d.ts +25 -0
  13. package/dist/connections/didKey.d.ts.map +1 -0
  14. package/dist/connections/didKey.js +49 -0
  15. package/dist/connections/didKey.js.map +1 -0
  16. package/dist/connections/entry.d.ts +226 -0
  17. package/dist/connections/entry.d.ts.map +1 -0
  18. package/dist/connections/entry.js +287 -0
  19. package/dist/connections/entry.js.map +1 -0
  20. package/dist/connections/errors.d.ts +33 -0
  21. package/dist/connections/errors.d.ts.map +1 -0
  22. package/dist/connections/errors.js +36 -0
  23. package/dist/connections/errors.js.map +1 -0
  24. package/dist/connections/grants.d.ts +94 -0
  25. package/dist/connections/grants.d.ts.map +1 -0
  26. package/dist/connections/grants.js +120 -0
  27. package/dist/connections/grants.js.map +1 -0
  28. package/dist/connections/index.d.ts +47 -0
  29. package/dist/connections/index.d.ts.map +1 -0
  30. package/dist/connections/index.js +40 -0
  31. package/dist/connections/index.js.map +1 -0
  32. package/dist/connections/read.d.ts +82 -0
  33. package/dist/connections/read.d.ts.map +1 -0
  34. package/dist/connections/read.js +100 -0
  35. package/dist/connections/read.js.map +1 -0
  36. package/dist/connections/resourceId.d.ts +36 -0
  37. package/dist/connections/resourceId.d.ts.map +1 -0
  38. package/dist/connections/resourceId.js +49 -0
  39. package/dist/connections/resourceId.js.map +1 -0
  40. package/dist/connections/store.d.ts +103 -0
  41. package/dist/connections/store.d.ts.map +1 -0
  42. package/dist/connections/store.js +67 -0
  43. package/dist/connections/store.js.map +1 -0
  44. package/dist/connections/upsert.d.ts +214 -0
  45. package/dist/connections/upsert.d.ts.map +1 -0
  46. package/dist/connections/upsert.js +468 -0
  47. package/dist/connections/upsert.js.map +1 -0
  48. package/dist/connections/writers.d.ts +217 -0
  49. package/dist/connections/writers.d.ts.map +1 -0
  50. package/dist/connections/writers.js +485 -0
  51. package/dist/connections/writers.js.map +1 -0
  52. package/dist/enrollment/onboardingResponse.d.ts +3 -3
  53. package/dist/enrollment/onboardingResponse.d.ts.map +1 -1
  54. package/dist/enrollment/onboardingResponse.js +17 -13
  55. package/dist/enrollment/onboardingResponse.js.map +1 -1
  56. package/dist/keys/index.d.ts +0 -7
  57. package/dist/keys/index.d.ts.map +1 -1
  58. package/dist/keys/index.js +0 -6
  59. package/dist/keys/index.js.map +1 -1
  60. package/dist/labelText.d.ts +30 -3
  61. package/dist/labelText.d.ts.map +1 -1
  62. package/dist/labelText.js +35 -3
  63. package/dist/labelText.js.map +1 -1
  64. package/dist/menders/ids.d.ts +1 -1
  65. package/dist/menders/ids.d.ts.map +1 -1
  66. package/dist/menders/ids.js +7 -2
  67. package/dist/menders/ids.js.map +1 -1
  68. package/dist/space/collections.d.ts +28 -25
  69. package/dist/space/collections.d.ts.map +1 -1
  70. package/dist/space/collections.js +46 -40
  71. package/dist/space/collections.js.map +1 -1
  72. package/dist/space/index.d.ts +4 -3
  73. package/dist/space/index.d.ts.map +1 -1
  74. package/dist/space/index.js +4 -3
  75. package/dist/space/index.js.map +1 -1
  76. package/package.json +8 -8
  77. package/dist/keys/clientLabels.d.ts +0 -85
  78. package/dist/keys/clientLabels.d.ts.map +0 -1
  79. package/dist/keys/clientLabels.js +0 -96
  80. package/dist/keys/clientLabels.js.map +0 -1
  81. package/dist/keys/wasLabelsStore.d.ts +0 -33
  82. package/dist/keys/wasLabelsStore.d.ts.map +0 -1
  83. package/dist/keys/wasLabelsStore.js +0 -35
  84. package/dist/keys/wasLabelsStore.js.map +0 -1
  85. package/dist/writers/entry.d.ts +0 -95
  86. package/dist/writers/entry.d.ts.map +0 -1
  87. package/dist/writers/entry.js +0 -90
  88. package/dist/writers/entry.js.map +0 -1
  89. package/dist/writers/index.d.ts +0 -17
  90. package/dist/writers/index.d.ts.map +0 -1
  91. package/dist/writers/index.js +0 -14
  92. package/dist/writers/index.js.map +0 -1
  93. package/dist/writers/roster.d.ts +0 -152
  94. package/dist/writers/roster.d.ts.map +0 -1
  95. package/dist/writers/roster.js +0 -365
  96. package/dist/writers/roster.js.map +0 -1
  97. package/dist/writers/store.d.ts +0 -71
  98. package/dist/writers/store.d.ts.map +0 -1
  99. package/dist/writers/store.js +0 -55
  100. package/dist/writers/store.js.map +0 -1
@@ -0,0 +1,94 @@
1
+ import type { ConnectionEntry, ConnectionZcap, GrantKind } from './entry.js';
2
+ /**
3
+ * One grant that passed the reader checks, with the members a decision
4
+ * reads taken off its capability.
5
+ */
6
+ export interface ConnectionGrant {
7
+ /**
8
+ * The capability's `id`, the key every merge and removal matches on.
9
+ */
10
+ zcapId: string;
11
+ /**
12
+ * The capability's `controller`, equal to the entry's `id`.
13
+ */
14
+ controller: string;
15
+ /**
16
+ * The capability's `invocationTarget`, under this Space's container URL.
17
+ */
18
+ target: string;
19
+ allowedAction?: string | string[];
20
+ expires?: string;
21
+ grantKind: GrantKind;
22
+ grantedAt: string;
23
+ /**
24
+ * The stored capability, verbatim: what a revocation POSTs.
25
+ */
26
+ zcap: ConnectionZcap;
27
+ }
28
+ /**
29
+ * Whether a capability target sits under a Space's container URL. The target
30
+ * is normalized by URL parsing first, so a dot segment cannot climb out of
31
+ * the Space.
32
+ *
33
+ * @param options {object}
34
+ * @param options.target {string}
35
+ * @param options.spaceUrl {string} the Space's container URL, with its
36
+ * trailing slash
37
+ * @returns {boolean}
38
+ */
39
+ export declare function isTargetInSpace({ target, spaceUrl }: {
40
+ target: string;
41
+ spaceUrl: string;
42
+ }): boolean;
43
+ /**
44
+ * The grants of one entry that pass the reader checks, in stored order. An
45
+ * entry with no `id` (a keyless writer entry) has no grant a controller can
46
+ * match, so none pass.
47
+ *
48
+ * @param options {object}
49
+ * @param options.entry {ConnectionEntry}
50
+ * @param options.spaceUrl {string} this Space's container URL
51
+ * @returns {ConnectionGrant[]}
52
+ */
53
+ export declare function connectionGrants({ entry, spaceUrl }: {
54
+ entry: ConnectionEntry;
55
+ spaceUrl: string;
56
+ }): ConnectionGrant[];
57
+ /**
58
+ * The distinct targets of a set of grants, in first-seen order.
59
+ *
60
+ * @param options {object}
61
+ * @param options.grants {ConnectionGrant[]}
62
+ * @returns {string[]}
63
+ */
64
+ export declare function grantTargets({ grants }: {
65
+ grants: ConnectionGrant[];
66
+ }): string[];
67
+ /**
68
+ * Splits grants into the live and the expired. A grant with no `expires` is
69
+ * live. One whose `expires` is at or before `now` is expired.
70
+ *
71
+ * @param options {object}
72
+ * @param options.grants {ConnectionGrant[]}
73
+ * @param [options.now] {Date}
74
+ * @returns {{ live: ConnectionGrant[], expired: ConnectionGrant[] }}
75
+ */
76
+ export declare function splitGrantsByExpiry({ grants, now }: {
77
+ grants: ConnectionGrant[];
78
+ now?: Date;
79
+ }): {
80
+ live: ConnectionGrant[];
81
+ expired: ConnectionGrant[];
82
+ };
83
+ /**
84
+ * The key-epoch recipient kid a grant's controller derives, or `undefined`
85
+ * when the controller is not an Ed25519 did:key.
86
+ *
87
+ * @param options {object}
88
+ * @param options.grant {ConnectionGrant}
89
+ * @returns {string | undefined}
90
+ */
91
+ export declare function grantRecipientKid({ grant }: {
92
+ grant: ConnectionGrant;
93
+ }): string | undefined;
94
+ //# sourceMappingURL=grants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../../src/connections/grants.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE5E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,IAAI,EAAE,cAAc,CAAA;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACT,EAAE;IACD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,OAAO,CAaV;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACT,EAAE;IACD,KAAK,EAAE,eAAe,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,eAAe,EAAE,CAyBpB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACP,EAAE;IACD,MAAM,EAAE,eAAe,EAAE,CAAA;CAC1B,GAAG,MAAM,EAAE,CAEX;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,GAAgB,EACjB,EAAE;IACD,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,GAAG,CAAC,EAAE,IAAI,CAAA;CACX,GAAG;IAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,CAc1D;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACN,EAAE;IACD,KAAK,EAAE,eAAe,CAAA;CACvB,GAAG,MAAM,GAAG,SAAS,CAErB"}
@@ -0,0 +1,120 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The grant index the revocation orchestrators share: the grants of one
6
+ * entry that pass the reader checks, their targets, the live and expired
7
+ * split, and the recipient kid a grant's controller derives.
8
+ *
9
+ * Every reader applies the same two checks, since the storage host can plant
10
+ * an entry and also holds every capability a party ever invoked. A grant
11
+ * whose `zcap.controller` is not the entry's `id` is dropped, so an entry at
12
+ * one party's id cannot steer a revocation at another party's capabilities.
13
+ * A grant whose `zcap.invocationTarget` is not under this Space's container
14
+ * URL is dropped, so no reader acts on a capability over another Space.
15
+ */
16
+ import { connectionRecipientKid } from './didKey.js';
17
+ import { grantKindOf } from './entry.js';
18
+ /**
19
+ * Whether a capability target sits under a Space's container URL. The target
20
+ * is normalized by URL parsing first, so a dot segment cannot climb out of
21
+ * the Space.
22
+ *
23
+ * @param options {object}
24
+ * @param options.target {string}
25
+ * @param options.spaceUrl {string} the Space's container URL, with its
26
+ * trailing slash
27
+ * @returns {boolean}
28
+ */
29
+ export function isTargetInSpace({ target, spaceUrl }) {
30
+ if (!spaceUrl.endsWith('/')) {
31
+ throw new TypeError(`A Space container URL ends with a slash; got "${spaceUrl}".`);
32
+ }
33
+ let normalized;
34
+ try {
35
+ normalized = new URL(target).href;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ return normalized.startsWith(new URL(spaceUrl).href);
41
+ }
42
+ /**
43
+ * The grants of one entry that pass the reader checks, in stored order. An
44
+ * entry with no `id` (a keyless writer entry) has no grant a controller can
45
+ * match, so none pass.
46
+ *
47
+ * @param options {object}
48
+ * @param options.entry {ConnectionEntry}
49
+ * @param options.spaceUrl {string} this Space's container URL
50
+ * @returns {ConnectionGrant[]}
51
+ */
52
+ export function connectionGrants({ entry, spaceUrl }) {
53
+ const grants = [];
54
+ for (const grant of entry.grants) {
55
+ const { zcap } = grant;
56
+ if (entry.id === undefined ||
57
+ zcap.controller !== entry.id ||
58
+ !isTargetInSpace({ target: zcap.invocationTarget, spaceUrl })) {
59
+ continue;
60
+ }
61
+ grants.push({
62
+ zcapId: zcap.id,
63
+ controller: zcap.controller,
64
+ target: zcap.invocationTarget,
65
+ ...(zcap.allowedAction !== undefined && {
66
+ allowedAction: zcap.allowedAction
67
+ }),
68
+ ...(zcap.expires !== undefined && { expires: zcap.expires }),
69
+ grantKind: grantKindOf(grant),
70
+ grantedAt: grant.grantedAt,
71
+ zcap
72
+ });
73
+ }
74
+ return grants;
75
+ }
76
+ /**
77
+ * The distinct targets of a set of grants, in first-seen order.
78
+ *
79
+ * @param options {object}
80
+ * @param options.grants {ConnectionGrant[]}
81
+ * @returns {string[]}
82
+ */
83
+ export function grantTargets({ grants }) {
84
+ return [...new Set(grants.map(grant => grant.target))];
85
+ }
86
+ /**
87
+ * Splits grants into the live and the expired. A grant with no `expires` is
88
+ * live. One whose `expires` is at or before `now` is expired.
89
+ *
90
+ * @param options {object}
91
+ * @param options.grants {ConnectionGrant[]}
92
+ * @param [options.now] {Date}
93
+ * @returns {{ live: ConnectionGrant[], expired: ConnectionGrant[] }}
94
+ */
95
+ export function splitGrantsByExpiry({ grants, now = new Date() }) {
96
+ const live = [];
97
+ const expired = [];
98
+ for (const grant of grants) {
99
+ if (grant.expires !== undefined &&
100
+ Date.parse(grant.expires) <= now.getTime()) {
101
+ expired.push(grant);
102
+ }
103
+ else {
104
+ live.push(grant);
105
+ }
106
+ }
107
+ return { live, expired };
108
+ }
109
+ /**
110
+ * The key-epoch recipient kid a grant's controller derives, or `undefined`
111
+ * when the controller is not an Ed25519 did:key.
112
+ *
113
+ * @param options {object}
114
+ * @param options.grant {ConnectionGrant}
115
+ * @returns {string | undefined}
116
+ */
117
+ export function grantRecipientKid({ grant }) {
118
+ return connectionRecipientKid({ did: grant.controller });
119
+ }
120
+ //# sourceMappingURL=grants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grants.js","sourceRoot":"","sources":["../../src/connections/grants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/connections` subpath: the `connections`
6
+ * directory, one encrypted entry per party the wallet has dealt with (an app,
7
+ * an agent, a wallet client, a contact). The wallet writes every entry, and
8
+ * no party ever writes one.
9
+ *
10
+ * - The entry codec (`parseConnectionEntry`), the `kind` and `grantKind`
11
+ * vocabularies, and the writer policy (`CONNECTION_WRITER_POLICY`).
12
+ * - `connectionResourceId`, the two-arm resource id keyed by the
13
+ * collection's blinded-index key.
14
+ * - The store seam and its WAS adapter (`wasConnectionsStore`), and the one
15
+ * listing read (`readConnections`) every lookup by DID resolves against.
16
+ * - The grant index the revocation orchestrators share
17
+ * (`connectionGrants`, `grantTargets`, `splitGrantsByExpiry`,
18
+ * `grantRecipientKid`), with the reader checks every reader applies.
19
+ * - The upsert helpers (`recordGrants`, `removeGrants`, `retireConnection`,
20
+ * `setConnectionLabel`) and their kind refusal
21
+ * (`ConnectionKindMismatchError`).
22
+ * - The writer arm: lazy registration (`registerConnectionWriter`), the
23
+ * pull-path touch (`touchConnectionWriter`), the per-entry sweep
24
+ * (`sweepConnectionWriters`), and `resolveWriter` for history views.
25
+ * - `signingKeyMultibaseOfDid`, the one join between a wallet client's entry
26
+ * and the account document, and `normalizeDisplayName`, the one name rule
27
+ * every producer writes `name` through.
28
+ */
29
+ export { CONNECTION_ENTRY_VERSION, CONNECTION_KINDS, CONNECTION_WRITER_POLICY, GRANT_KINDS, connectionKindOf, connectionWriterPolicy, grantKindOf, isWritableConnectionEntry, parseConnectionEntry } from './entry.js';
30
+ export type { ConnectionEntry, ConnectionGrantRecord, ConnectionKind, ConnectionWriter, ConnectionWriterPolicy, ConnectionZcap, GrantKind } from './entry.js';
31
+ export { CONNECTIONS_ID_PREFIX, connectionResourceId } from './resourceId.js';
32
+ export type { ConnectionIdKey } from './resourceId.js';
33
+ export { wasConnectionsStore } from './store.js';
34
+ export type { ConnectionsStore, StoredConnection } from './store.js';
35
+ export { findConnection, readConnections } from './read.js';
36
+ export type { ConnectionsListing, ReadConnection } from './read.js';
37
+ export { connectionGrants, grantRecipientKid, grantTargets, isTargetInSpace, splitGrantsByExpiry } from './grants.js';
38
+ export type { ConnectionGrant } from './grants.js';
39
+ export { connectionRecipientKid, signingKeyMultibaseOfDid } from './didKey.js';
40
+ export { ConnectionKindMismatchError } from './errors.js';
41
+ export { recordGrants, removeGrants, retireConnection, setConnectionLabel } from './upsert.js';
42
+ export type { ConnectionWriteOutcome, ConnectionWriteResult } from './upsert.js';
43
+ export { registerConnectionWriter, resolveWriter, sweepConnectionWriters, touchConnectionWriter } from './writers.js';
44
+ export type { ConnectionWritersSweep, ResolvedWriter, WriterFirstSeenRecord, WriterFirstSeenStore, WriterRegistrationOutcome, WriterTouchOutcome } from './writers.js';
45
+ export { normalizeDisplayName } from '../labelText.js';
46
+ export { CONNECTIONS_COLLECTION } from '../space/collections.js';
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connections/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,SAAS,EACV,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AACnE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACpB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAChF,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -0,0 +1,40 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The `@interop/wallet-core/connections` subpath: the `connections`
6
+ * directory, one encrypted entry per party the wallet has dealt with (an app,
7
+ * an agent, a wallet client, a contact). The wallet writes every entry, and
8
+ * no party ever writes one.
9
+ *
10
+ * - The entry codec (`parseConnectionEntry`), the `kind` and `grantKind`
11
+ * vocabularies, and the writer policy (`CONNECTION_WRITER_POLICY`).
12
+ * - `connectionResourceId`, the two-arm resource id keyed by the
13
+ * collection's blinded-index key.
14
+ * - The store seam and its WAS adapter (`wasConnectionsStore`), and the one
15
+ * listing read (`readConnections`) every lookup by DID resolves against.
16
+ * - The grant index the revocation orchestrators share
17
+ * (`connectionGrants`, `grantTargets`, `splitGrantsByExpiry`,
18
+ * `grantRecipientKid`), with the reader checks every reader applies.
19
+ * - The upsert helpers (`recordGrants`, `removeGrants`, `retireConnection`,
20
+ * `setConnectionLabel`) and their kind refusal
21
+ * (`ConnectionKindMismatchError`).
22
+ * - The writer arm: lazy registration (`registerConnectionWriter`), the
23
+ * pull-path touch (`touchConnectionWriter`), the per-entry sweep
24
+ * (`sweepConnectionWriters`), and `resolveWriter` for history views.
25
+ * - `signingKeyMultibaseOfDid`, the one join between a wallet client's entry
26
+ * and the account document, and `normalizeDisplayName`, the one name rule
27
+ * every producer writes `name` through.
28
+ */
29
+ export { CONNECTION_ENTRY_VERSION, CONNECTION_KINDS, CONNECTION_WRITER_POLICY, GRANT_KINDS, connectionKindOf, connectionWriterPolicy, grantKindOf, isWritableConnectionEntry, parseConnectionEntry } from './entry.js';
30
+ export { CONNECTIONS_ID_PREFIX, connectionResourceId } from './resourceId.js';
31
+ export { wasConnectionsStore } from './store.js';
32
+ export { findConnection, readConnections } from './read.js';
33
+ export { connectionGrants, grantRecipientKid, grantTargets, isTargetInSpace, splitGrantsByExpiry } from './grants.js';
34
+ export { connectionRecipientKid, signingKeyMultibaseOfDid } from './didKey.js';
35
+ export { ConnectionKindMismatchError } from './errors.js';
36
+ export { recordGrants, removeGrants, retireConnection, setConnectionLabel } from './upsert.js';
37
+ export { registerConnectionWriter, resolveWriter, sweepConnectionWriters, touchConnectionWriter } from './writers.js';
38
+ export { normalizeDisplayName } from '../labelText.js';
39
+ export { CONNECTIONS_COLLECTION } from '../space/collections.js';
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connections/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,WAAW,EACX,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,YAAY,CAAA;AAUnB,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACpB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAC9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,cAAc,CAAA;AASrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -0,0 +1,82 @@
1
+ import type { ConnectionEntry } from './entry.js';
2
+ import type { ConnectionIdKey } from './resourceId.js';
3
+ import type { ConnectionsStore } from './store.js';
4
+ /**
5
+ * One entry a listing found at its own resource id.
6
+ */
7
+ export interface ReadConnection {
8
+ resourceId: string;
9
+ etag?: string;
10
+ /**
11
+ * The members this build knows, as the codec read them.
12
+ */
13
+ entry: ConnectionEntry;
14
+ /**
15
+ * The stored body verbatim, every member included. A writer starts from
16
+ * this so the members it does not own survive.
17
+ */
18
+ body: Record<string, unknown>;
19
+ }
20
+ /**
21
+ * What one listing read found. A resource that sits at an id its own `id`
22
+ * (or its one writer) does not derive to is ignored and reported nowhere: it
23
+ * is a copy, a misplaced write, or a planted body, and labels nothing.
24
+ */
25
+ export interface ConnectionsListing {
26
+ /**
27
+ * The parseable entries at their own ids, newer-version ones included.
28
+ */
29
+ entries: ReadConnection[];
30
+ /**
31
+ * Resources the store could not open (an unknown epoch, a key this reader
32
+ * does not hold).
33
+ */
34
+ unreadable: string[];
35
+ /**
36
+ * Resources at their own id whose body the codec refuses. Such a body may
37
+ * still vouch for a party this build cannot see.
38
+ */
39
+ unparseable: string[];
40
+ }
41
+ /**
42
+ * The resource id a stored body claims by its own members: its `id`, or its
43
+ * one writer's `writerId` when it carries no `id`. `undefined` when the body
44
+ * names neither.
45
+ *
46
+ * @param options {object}
47
+ * @param options.body {unknown}
48
+ * @param options.hmacKey {ConnectionIdKey}
49
+ * @returns {Promise<string | undefined>}
50
+ */
51
+ export declare function claimedResourceId({ body, hmacKey }: {
52
+ body: unknown;
53
+ hmacKey: ConnectionIdKey;
54
+ }): Promise<string | undefined>;
55
+ /**
56
+ * Reads the whole directory once. Returns `null` when the collection is
57
+ * absent or not visible, which a caller deciding anything about a party
58
+ * treats as a failure rather than as an empty directory.
59
+ *
60
+ * @param options {object}
61
+ * @param options.store {ConnectionsStore}
62
+ * @param options.hmacKey {ConnectionIdKey} the collection's blinded-index
63
+ * key
64
+ * @returns {Promise<ConnectionsListing | null>}
65
+ */
66
+ export declare function readConnections({ store, hmacKey }: {
67
+ store: ConnectionsStore;
68
+ hmacKey: ConnectionIdKey;
69
+ }): Promise<ConnectionsListing | null>;
70
+ /**
71
+ * The listed entry whose `id` is the given DID, matched in memory.
72
+ *
73
+ * @param options {object}
74
+ * @param options.listing {ConnectionsListing}
75
+ * @param options.did {string}
76
+ * @returns {ReadConnection | undefined}
77
+ */
78
+ export declare function findConnection({ listing, did }: {
79
+ listing: ConnectionsListing;
80
+ did: string;
81
+ }): ReadConnection | undefined;
82
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/connections/read.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,KAAK,EAAE,eAAe,CAAA;IACtB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB;;;OAGG;IACH,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB;;;OAGG;IACH,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,IAAI,EACJ,OAAO,EACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,eAAe,CAAA;CACzB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAe9B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,EACpC,KAAK,EACL,OAAO,EACR,EAAE;IACD,KAAK,EAAE,gBAAgB,CAAA;IACvB,OAAO,EAAE,eAAe,CAAA;CACzB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAwCrC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,GAAG,EACJ,EAAE;IACD,OAAO,EAAE,kBAAkB,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,cAAc,GAAG,SAAS,CAE7B"}
@@ -0,0 +1,100 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The directory listing read: one pass over the store, each body parsed and
6
+ * checked against the resource id it sits at.
7
+ *
8
+ * Every lookup by DID outside consent resolves against this one read,
9
+ * matching on the decrypted `id` in memory. A wallet does not GET the id a DID
10
+ * derives to just to look the party up, since the host would then learn which
11
+ * id belongs to which DID and whether that DID has an entry.
12
+ */
13
+ import { isJsonObject, parseConnectionEntry } from './entry.js';
14
+ import { connectionResourceId } from './resourceId.js';
15
+ /**
16
+ * The resource id a stored body claims by its own members: its `id`, or its
17
+ * one writer's `writerId` when it carries no `id`. `undefined` when the body
18
+ * names neither.
19
+ *
20
+ * @param options {object}
21
+ * @param options.body {unknown}
22
+ * @param options.hmacKey {ConnectionIdKey}
23
+ * @returns {Promise<string | undefined>}
24
+ */
25
+ export async function claimedResourceId({ body, hmacKey }) {
26
+ if (!isJsonObject(body)) {
27
+ return undefined;
28
+ }
29
+ if (typeof body.id === 'string') {
30
+ return connectionResourceId({ hmacKey, did: body.id });
31
+ }
32
+ const writers = body.writers;
33
+ if (Array.isArray(writers) && writers.length === 1) {
34
+ const [writer] = writers;
35
+ if (isJsonObject(writer) && typeof writer.writerId === 'string') {
36
+ return connectionResourceId({ hmacKey, writerId: writer.writerId });
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+ /**
42
+ * Reads the whole directory once. Returns `null` when the collection is
43
+ * absent or not visible, which a caller deciding anything about a party
44
+ * treats as a failure rather than as an empty directory.
45
+ *
46
+ * @param options {object}
47
+ * @param options.store {ConnectionsStore}
48
+ * @param options.hmacKey {ConnectionIdKey} the collection's blinded-index
49
+ * key
50
+ * @returns {Promise<ConnectionsListing | null>}
51
+ */
52
+ export async function readConnections({ store, hmacKey }) {
53
+ const stored = await store.list();
54
+ if (stored === null) {
55
+ return null;
56
+ }
57
+ const listing = {
58
+ entries: [],
59
+ unreadable: [],
60
+ unparseable: []
61
+ };
62
+ // The claimed ids are independent HMACs, derived together rather than one
63
+ // awaited at a time when the key is the async `sign` form.
64
+ const claims = await Promise.all(stored.map(item => item.readError !== undefined || item.body === undefined
65
+ ? undefined
66
+ : claimedResourceId({ body: item.body, hmacKey })));
67
+ for (const [index, item] of stored.entries()) {
68
+ if (item.readError !== undefined || item.body === undefined) {
69
+ listing.unreadable.push(item.resourceId);
70
+ continue;
71
+ }
72
+ if (claims[index] !== item.resourceId) {
73
+ continue;
74
+ }
75
+ const entry = parseConnectionEntry(item.body);
76
+ if (entry === undefined) {
77
+ listing.unparseable.push(item.resourceId);
78
+ continue;
79
+ }
80
+ listing.entries.push({
81
+ resourceId: item.resourceId,
82
+ ...(item.etag !== undefined && { etag: item.etag }),
83
+ entry,
84
+ body: item.body
85
+ });
86
+ }
87
+ return listing;
88
+ }
89
+ /**
90
+ * The listed entry whose `id` is the given DID, matched in memory.
91
+ *
92
+ * @param options {object}
93
+ * @param options.listing {ConnectionsListing}
94
+ * @param options.did {string}
95
+ * @returns {ReadConnection | undefined}
96
+ */
97
+ export function findConnection({ listing, did }) {
98
+ return listing.entries.find(item => item.entry.id === did);
99
+ }
100
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/connections/read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The domain prefix of every directory resource id.
3
+ */
4
+ export declare const CONNECTIONS_ID_PREFIX = "connections/v1";
5
+ /**
6
+ * The collection's blinded-index key, in either form a wallet holds it: the
7
+ * raw 32-byte secret, or the resolved key whose `sign` is HMAC-SHA-256 over
8
+ * that secret (was-client's `BlindingKey`, as `resolveHmacKey` returns it).
9
+ * Both derive the same ids.
10
+ */
11
+ export type ConnectionIdKey = Uint8Array | {
12
+ sign(options: {
13
+ data: Uint8Array;
14
+ }): Promise<Uint8Array>;
15
+ };
16
+ /**
17
+ * The resource id of a party's entry (`did`) or of a keyless writer's entry
18
+ * (`writerId`). Exactly one of the two is given.
19
+ *
20
+ * @param options {object}
21
+ * @param options.hmacKey {ConnectionIdKey} the collection's blinded-index
22
+ * key
23
+ * @param [options.did] {string} the party's DID
24
+ * @param [options.writerId] {string} a keyless writer's `writerId`
25
+ * @returns {Promise<string>}
26
+ */
27
+ export declare function connectionResourceId(options: {
28
+ hmacKey: ConnectionIdKey;
29
+ did: string;
30
+ writerId?: undefined;
31
+ } | {
32
+ hmacKey: ConnectionIdKey;
33
+ writerId: string;
34
+ did?: undefined;
35
+ }): Promise<string>;
36
+ //# sourceMappingURL=resourceId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceId.d.ts","sourceRoot":"","sources":["../../src/connections/resourceId.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,eAAO,MAAM,qBAAqB,mBAAmB,CAAA;AAErD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACzB,UAAU,GAAG;IAAE,IAAI,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;CAAE,CAAA;AAE3E;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EACH;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,GAC/D;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,SAAS,CAAA;CAAE,GAClE,OAAO,CAAC,MAAM,CAAC,CAcjB"}
@@ -0,0 +1,49 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The directory's resource id: where one party's entry lives.
6
+ *
7
+ * The id is the first 16 bytes of
8
+ * `HMAC-SHA-256(hmacKey, utf8('connections/v1' + '|' + armInput))`, formatted
9
+ * with was-client's `edvIdFromBytes`. `hmacKey` is the collection's
10
+ * blinded-index key. `armInput` is `'did:' + did` for a party with a DID and
11
+ * `'writer:' + writerId` for a keyless writer. The account DID is not an
12
+ * input.
13
+ *
14
+ * Keying the id stops the storage host from computing the id of a guessed
15
+ * DID and probing for it. The protection lasts only while reads keep it: a
16
+ * wallet does not GET an id derived from a DID the host or a request
17
+ * supplied, except at consent for the party it is about to grant.
18
+ */
19
+ import { hmac } from '@noble/hashes/hmac.js';
20
+ import { sha256 } from '@noble/hashes/sha2.js';
21
+ import { edvIdFromBytes } from '@interop/was-client/edv/cipher';
22
+ /**
23
+ * The domain prefix of every directory resource id.
24
+ */
25
+ export const CONNECTIONS_ID_PREFIX = 'connections/v1';
26
+ /**
27
+ * The resource id of a party's entry (`did`) or of a keyless writer's entry
28
+ * (`writerId`). Exactly one of the two is given.
29
+ *
30
+ * @param options {object}
31
+ * @param options.hmacKey {ConnectionIdKey} the collection's blinded-index
32
+ * key
33
+ * @param [options.did] {string} the party's DID
34
+ * @param [options.writerId] {string} a keyless writer's `writerId`
35
+ * @returns {Promise<string>}
36
+ */
37
+ export async function connectionResourceId(options) {
38
+ const { hmacKey, did, writerId } = options;
39
+ if ((did === undefined) === (writerId === undefined)) {
40
+ throw new TypeError('A connection resource id takes exactly one of "did" and "writerId".');
41
+ }
42
+ const armInput = did !== undefined ? `did:${did}` : `writer:${writerId}`;
43
+ const data = new TextEncoder().encode(`${CONNECTIONS_ID_PREFIX}|${armInput}`);
44
+ const mac = hmacKey instanceof Uint8Array
45
+ ? hmac(sha256, hmacKey, data)
46
+ : await hmacKey.sign({ data });
47
+ return edvIdFromBytes(mac.subarray(0, 16));
48
+ }
49
+ //# sourceMappingURL=resourceId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resourceId.js","sourceRoot":"","sources":["../../src/connections/resourceId.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAE/D;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,CAAA;AAWrD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAEmE;IAEnE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IAC1C,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,SAAS,CACjB,qEAAqE,CACtE,CAAA;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,QAAQ,EAAE,CAAA;IACxE,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,qBAAqB,IAAI,QAAQ,EAAE,CAAC,CAAA;IAC7E,MAAM,GAAG,GACP,OAAO,YAAY,UAAU;QAC3B,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QAC7B,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;IAClC,OAAO,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5C,CAAC"}