@interop/wallet-core 0.94.0 → 0.96.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 +21 -20
- package/dist/clientAnnex/mend.js +4 -1
- package/dist/clientAnnex/mend.js.map +1 -1
- package/dist/clients/index.d.ts +3 -2
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +3 -2
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/listing.d.ts +19 -12
- package/dist/clients/listing.d.ts.map +1 -1
- package/dist/clients/listing.js +69 -22
- package/dist/clients/listing.js.map +1 -1
- package/dist/connections/didKey.d.ts +25 -0
- package/dist/connections/didKey.d.ts.map +1 -0
- package/dist/connections/didKey.js +49 -0
- package/dist/connections/didKey.js.map +1 -0
- package/dist/connections/entry.d.ts +226 -0
- package/dist/connections/entry.d.ts.map +1 -0
- package/dist/connections/entry.js +287 -0
- package/dist/connections/entry.js.map +1 -0
- package/dist/connections/errors.d.ts +33 -0
- package/dist/connections/errors.d.ts.map +1 -0
- package/dist/connections/errors.js +36 -0
- package/dist/connections/errors.js.map +1 -0
- package/dist/connections/grants.d.ts +94 -0
- package/dist/connections/grants.d.ts.map +1 -0
- package/dist/connections/grants.js +120 -0
- package/dist/connections/grants.js.map +1 -0
- package/dist/connections/index.d.ts +47 -0
- package/dist/connections/index.d.ts.map +1 -0
- package/dist/connections/index.js +40 -0
- package/dist/connections/index.js.map +1 -0
- package/dist/connections/read.d.ts +82 -0
- package/dist/connections/read.d.ts.map +1 -0
- package/dist/connections/read.js +100 -0
- package/dist/connections/read.js.map +1 -0
- package/dist/connections/resourceId.d.ts +36 -0
- package/dist/connections/resourceId.d.ts.map +1 -0
- package/dist/connections/resourceId.js +49 -0
- package/dist/connections/resourceId.js.map +1 -0
- package/dist/connections/store.d.ts +103 -0
- package/dist/connections/store.d.ts.map +1 -0
- package/dist/connections/store.js +67 -0
- package/dist/connections/store.js.map +1 -0
- package/dist/connections/upsert.d.ts +220 -0
- package/dist/connections/upsert.d.ts.map +1 -0
- package/dist/connections/upsert.js +478 -0
- package/dist/connections/upsert.js.map +1 -0
- package/dist/connections/writers.d.ts +217 -0
- package/dist/connections/writers.d.ts.map +1 -0
- package/dist/connections/writers.js +485 -0
- package/dist/connections/writers.js.map +1 -0
- package/dist/enrollment/onboardingResponse.d.ts +3 -3
- package/dist/enrollment/onboardingResponse.d.ts.map +1 -1
- package/dist/enrollment/onboardingResponse.js +17 -13
- package/dist/enrollment/onboardingResponse.js.map +1 -1
- package/dist/keys/index.d.ts +0 -7
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +0 -6
- package/dist/keys/index.js.map +1 -1
- package/dist/labelText.d.ts +30 -3
- package/dist/labelText.d.ts.map +1 -1
- package/dist/labelText.js +35 -3
- package/dist/labelText.js.map +1 -1
- package/dist/menders/ids.d.ts +1 -1
- package/dist/menders/ids.d.ts.map +1 -1
- package/dist/menders/ids.js +7 -2
- package/dist/menders/ids.js.map +1 -1
- package/dist/space/collections.d.ts +15 -25
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +19 -29
- package/dist/space/collections.js.map +1 -1
- package/dist/space/index.d.ts +4 -3
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +4 -3
- package/dist/space/index.js.map +1 -1
- package/package.json +8 -8
- package/dist/keys/clientLabels.d.ts +0 -85
- package/dist/keys/clientLabels.d.ts.map +0 -1
- package/dist/keys/clientLabels.js +0 -96
- package/dist/keys/clientLabels.js.map +0 -1
- package/dist/keys/wasLabelsStore.d.ts +0 -33
- package/dist/keys/wasLabelsStore.d.ts.map +0 -1
- package/dist/keys/wasLabelsStore.js +0 -35
- package/dist/keys/wasLabelsStore.js.map +0 -1
- package/dist/writers/entry.d.ts +0 -95
- package/dist/writers/entry.d.ts.map +0 -1
- package/dist/writers/entry.js +0 -90
- package/dist/writers/entry.js.map +0 -1
- package/dist/writers/index.d.ts +0 -17
- package/dist/writers/index.d.ts.map +0 -1
- package/dist/writers/index.js +0 -14
- package/dist/writers/index.js.map +0 -1
- package/dist/writers/roster.d.ts +0 -152
- package/dist/writers/roster.d.ts.map +0 -1
- package/dist/writers/roster.js +0 -365
- package/dist/writers/roster.js.map +0 -1
- package/dist/writers/store.d.ts +0 -71
- package/dist/writers/store.d.ts.map +0 -1
- package/dist/writers/store.js +0 -55
- 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"}
|