@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.
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 +220 -0
  45. package/dist/connections/upsert.d.ts.map +1 -0
  46. package/dist/connections/upsert.js +478 -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 +15 -25
  69. package/dist/space/collections.d.ts.map +1 -1
  70. package/dist/space/collections.js +19 -29
  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
@@ -1,96 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * Enrolled-client display labels: the `key-map/client-labels.json` record, a
6
- * plain-JSON map from a client's signing-key multibase to the human-chosen
7
- * label a "your wallets" surface shows. The did:webvh document is the roster
8
- * of record and deliberately carries key material only, so labels live
9
- * beside the account's other key-map resources instead -- private,
10
- * capability-gated, and shared by every enrolled client (each wallet app
11
- * reads and writes the same record).
12
- *
13
- * The record is display metadata with no authority: a missing or malformed
14
- * record degrades to unlabeled rows, an entry whose key the document no
15
- * longer lists is simply never shown, and writes are last-write-wins (a lost
16
- * race costs at most a label). I/O runs through the two-method
17
- * {@link ClientLabelsStore} seam a wallet app satisfies with its own
18
- * remote-store class.
19
- */
20
- /**
21
- * Reads the labels record, degrading to an empty record when it is missing
22
- * or malformed (labels are display metadata; a broken record must never
23
- * block a listing).
24
- *
25
- * @param options {object}
26
- * @param options.store {ClientLabelsStore}
27
- * @returns {Promise<ClientLabelsRecord>}
28
- */
29
- export async function readClientLabels({ store }) {
30
- let body;
31
- try {
32
- body = await store.get();
33
- }
34
- catch {
35
- return { version: 1, labels: {} };
36
- }
37
- if (body === null || typeof body !== 'object') {
38
- return { version: 1, labels: {} };
39
- }
40
- const { version, labels } = body;
41
- if (version !== 1 || labels === null || typeof labels !== 'object') {
42
- return { version: 1, labels: {} };
43
- }
44
- const parsed = {};
45
- for (const [key, value] of Object.entries(labels)) {
46
- if (typeof value === 'string') {
47
- parsed[key] = value;
48
- }
49
- }
50
- return { version: 1, labels: parsed };
51
- }
52
- /**
53
- * Sets (or renames) one client's label, read-modify-write over the stored
54
- * record. A blank label removes the entry instead of storing whitespace.
55
- *
56
- * @param options {object}
57
- * @param options.store {ClientLabelsStore}
58
- * @param options.signingKeyMultibase {string}
59
- * @param options.label {string}
60
- * @returns {Promise<ClientLabelsRecord>} the record as written
61
- */
62
- export async function setClientLabel({ store, signingKeyMultibase, label }) {
63
- const trimmed = label.trim();
64
- if (!trimmed) {
65
- return removeClientLabel({ store, signingKeyMultibase });
66
- }
67
- const record = await readClientLabels({ store });
68
- const updated = {
69
- version: 1,
70
- labels: { ...record.labels, [signingKeyMultibase]: trimmed }
71
- };
72
- await store.put({ content: updated });
73
- return updated;
74
- }
75
- /**
76
- * Drops one client's label (revocation hygiene -- the label of a
77
- * disconnected client points at nothing). A record without the entry is a
78
- * no-op that writes nothing.
79
- *
80
- * @param options {object}
81
- * @param options.store {ClientLabelsStore}
82
- * @param options.signingKeyMultibase {string}
83
- * @returns {Promise<ClientLabelsRecord>} the record as stored
84
- */
85
- export async function removeClientLabel({ store, signingKeyMultibase }) {
86
- const record = await readClientLabels({ store });
87
- if (!(signingKeyMultibase in record.labels)) {
88
- return record;
89
- }
90
- const labels = { ...record.labels };
91
- delete labels[signingKeyMultibase];
92
- const updated = { version: 1, labels };
93
- await store.put({ content: updated });
94
- return updated;
95
- }
96
- //# sourceMappingURL=clientLabels.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clientLabels.js","sourceRoot":"","sources":["../../src/keys/clientLabels.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;GAeG;AA0BH;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,KAAK,EAGN;IACC,IAAI,IAAa,CAAA;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACnC,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACnC,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAA+C,CAAA;IAC3E,IAAI,OAAO,KAAK,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACnE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACnC,CAAC;IACD,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACrB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AACvC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,EACnC,KAAK,EACL,mBAAmB,EACnB,KAAK,EAKN;IACC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,iBAAiB,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;IAC1D,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAChD,MAAM,OAAO,GAAuB;QAClC,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE;KAC7D,CAAA;IACD,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IACrC,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EACtC,KAAK,EACL,mBAAmB,EAIpB;IACC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;IAChD,IAAI,CAAC,CAAC,mBAAmB,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,OAAO,MAAM,CAAA;IACf,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;IACnC,OAAO,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAClC,MAAM,OAAO,GAAuB,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1D,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IACrC,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -1,33 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * The WAS-backed adapter for the enrolled-client display labels
6
- * (`key-map/client-labels.json`): the {@link ClientLabelsStore} seam the label
7
- * helpers read and write through, over the same private, plaintext `key-map`
8
- * collection the wrap-set roster lives in. Every wallet app on the account
9
- * shares this one implementation, so they share one record.
10
- */
11
- import type { IZcap } from '@interop/data-integrity-core';
12
- import type { WasClient } from '@interop/was-client';
13
- import type { ClientLabelsStore } from './clientLabels.js';
14
- /**
15
- * Builds the labels store over `key-map/client-labels.json` in a data Space.
16
- *
17
- * @param options {object}
18
- * @param options.was {WasClient} the account's storage client, signing as an
19
- * enrolled client or, under a delegated capability, as the annex
20
- * verification method
21
- * @param options.spaceId {string} the data Space id
22
- * @param [options.capability] {IZcap} an invocation capability the read and
23
- * the write both ride (a delegated Space-subtree zcap -- a transient
24
- * session's generation delegation); absent, both invoke the root capability
25
- * as before
26
- * @returns {ClientLabelsStore}
27
- */
28
- export declare function wasClientLabelsStore({ was, spaceId, capability }: {
29
- was: WasClient;
30
- spaceId: string;
31
- capability?: IZcap;
32
- }): ClientLabelsStore;
33
- //# sourceMappingURL=wasLabelsStore.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wasLabelsStore.d.ts","sourceRoot":"","sources":["../../src/keys/wasLabelsStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAA;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAMpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,GAAG,EACH,OAAO,EACP,UAAU,EACX,EAAE;IACD,GAAG,EAAE,SAAS,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,KAAK,CAAA;CACnB,GAAG,iBAAiB,CAiBpB"}
@@ -1,35 +0,0 @@
1
- import { CLIENT_LABELS_RESOURCE, KEY_MAP_COLLECTION } from '../space/collections.js';
2
- import { plaintextCollection } from '../space/plaintextCollection.js';
3
- /**
4
- * Builds the labels store over `key-map/client-labels.json` in a data Space.
5
- *
6
- * @param options {object}
7
- * @param options.was {WasClient} the account's storage client, signing as an
8
- * enrolled client or, under a delegated capability, as the annex
9
- * verification method
10
- * @param options.spaceId {string} the data Space id
11
- * @param [options.capability] {IZcap} an invocation capability the read and
12
- * the write both ride (a delegated Space-subtree zcap -- a transient
13
- * session's generation delegation); absent, both invoke the root capability
14
- * as before
15
- * @returns {ClientLabelsStore}
16
- */
17
- export function wasClientLabelsStore({ was, spaceId, capability }) {
18
- const resource = plaintextCollection({
19
- was,
20
- spaceId,
21
- collectionId: KEY_MAP_COLLECTION.id,
22
- capability
23
- }).resource(CLIENT_LABELS_RESOURCE);
24
- return {
25
- async get() {
26
- const result = await resource.get();
27
- return result === null ? undefined : result;
28
- },
29
- async put({ content }) {
30
- const body = new TextEncoder().encode(JSON.stringify(content));
31
- await resource.put(body, { contentType: 'application/json' });
32
- }
33
- };
34
- }
35
- //# sourceMappingURL=wasLabelsStore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wasLabelsStore.js","sourceRoot":"","sources":["../../src/keys/wasLabelsStore.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AAGrE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,GAAG,EACH,OAAO,EACP,UAAU,EAKX;IACC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;QACnC,GAAG;QACH,OAAO;QACP,YAAY,EAAE,kBAAkB,CAAC,EAAE;QACnC,UAAU;KACX,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAA;IACnC,OAAO;QACL,KAAK,CAAC,GAAG;YACP,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAA;YACnC,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;QAC7C,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAuB;YACxC,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;YAC9D,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAA;QAC/D,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1,95 +0,0 @@
1
- /**
2
- * The version-1 roster entry. A type alias rather than an interface, so it
3
- * is assignable to was-client's `JsonObject`.
4
- */
5
- export type RegisteredWriterEntry = {
6
- version: 1;
7
- /**
8
- * The writer's `writerId`, verbatim. The resource id is a hash of it, so a
9
- * reader takes the id from here.
10
- */
11
- writerId: string;
12
- /**
13
- * An enrolled wallet client's own signing-key multibase, the key the
14
- * client-labels record and `listAccountClients` rows are keyed by. Absent
15
- * for a non-wallet writer.
16
- */
17
- signingKeyMultibase?: string;
18
- /**
19
- * A coarse platform self-description, or the user's rename of it.
20
- */
21
- label: string;
22
- /**
23
- * ISO 8601 UTC timestamp of the writer's latest liveness touch.
24
- */
25
- lastSeen: string;
26
- /**
27
- * `false` once a sweep found `lastSeen` past the inactivity TTL. The writer's
28
- * next touch sets it back to `true`.
29
- */
30
- active: boolean;
31
- };
32
- /**
33
- * The expiry and liveness policy of the roster. Every replica that sweeps
34
- * must use the same values, or two sweepers disagree about which entries are
35
- * orphans.
36
- */
37
- export interface RegisteredWriterPolicy {
38
- /**
39
- * How long an entry may go untouched before a sweep marks it inactive.
40
- */
41
- inactiveAfterMs: number;
42
- /**
43
- * The entry count past which a sweep (or an enrollment) deletes the
44
- * oldest-`lastSeen` entries.
45
- */
46
- maxEntries: number;
47
- /**
48
- * The least time between two liveness touches by the same writer.
49
- */
50
- touchIntervalMs: number;
51
- }
52
- /**
53
- * The default policy: inactive after 90 days, at most 64 entries, touched at
54
- * most once a day. A wallet that overrides any of these passes the same
55
- * override on every replica.
56
- */
57
- export declare const REGISTERED_WRITER_POLICY: RegisteredWriterPolicy;
58
- /**
59
- * The domain label of the resource id hash.
60
- */
61
- export declare const REGISTERED_WRITER_ID_LABEL = "registered-writers/v1";
62
- /**
63
- * The resource id of one writer's entry under one account: the first 16
64
- * bytes of `sha256(utf8('registered-writers/v1|' + accountDid + '|' +
65
- * writerId))`, formatted as an EDV document id.
66
- *
67
- * The id is deterministic, so a registration and a touch are idempotent
68
- * upserts. It hides the `writerId` from the storage host and does not link
69
- * one `writerId` across accounts.
70
- *
71
- * @param options {object}
72
- * @param options.accountDid {string} the account whose Space holds the roster
73
- * @param options.writerId {string}
74
- * @returns {string}
75
- */
76
- export declare function registeredWriterResourceId({ accountDid, writerId }: {
77
- accountDid: string;
78
- writerId: string;
79
- }): string;
80
- /**
81
- * Resolves a partial policy override against the defaults.
82
- *
83
- * @param [policy] {Partial<RegisteredWriterPolicy>}
84
- * @returns {RegisteredWriterPolicy}
85
- */
86
- export declare function registeredWriterPolicy(policy?: Partial<RegisteredWriterPolicy>): RegisteredWriterPolicy;
87
- /**
88
- * Reads a stored body as a roster entry, or `undefined` when it is not one.
89
- * A malformed entry is skipped by every reader, and never repaired.
90
- *
91
- * @param body {unknown}
92
- * @returns {RegisteredWriterEntry | undefined}
93
- */
94
- export declare function parseRegisteredWriterEntry(body: unknown): RegisteredWriterEntry | undefined;
95
- //# sourceMappingURL=entry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/writers/entry.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,CAAC,CAAA;IACV;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;CACxB;AAID;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,sBAItC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,0BAA0B,0BAA0B,CAAA;AAEjE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,UAAU,EACV,QAAQ,EACT,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,MAAM,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,GACvC,sBAAsB,CAExB;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,OAAO,GACZ,qBAAqB,GAAG,SAAS,CA2BnC"}
@@ -1,90 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * The writer roster's entry: its version-1 shape, the shape check every
6
- * reader runs, the resource id an entry lives at, and the expiry policy both
7
- * wallets sweep under.
8
- *
9
- * An entry is advisory display data. Its writer asserts every field about
10
- * itself, and nothing checks them beyond shape. `signingKeyMultibase` links a
11
- * wallet writer to its enrolled client only when the verified did:webvh
12
- * document lists that key, and no field is an input to any authorization.
13
- */
14
- import { sha256 } from '@noble/hashes/sha2.js';
15
- import { edvIdFromBytes } from '@interop/was-client/edv/cipher';
16
- const DAY_MS = 24 * 60 * 60 * 1000;
17
- /**
18
- * The default policy: inactive after 90 days, at most 64 entries, touched at
19
- * most once a day. A wallet that overrides any of these passes the same
20
- * override on every replica.
21
- */
22
- export const REGISTERED_WRITER_POLICY = {
23
- inactiveAfterMs: 90 * DAY_MS,
24
- maxEntries: 64,
25
- touchIntervalMs: DAY_MS
26
- };
27
- /**
28
- * The domain label of the resource id hash.
29
- */
30
- export const REGISTERED_WRITER_ID_LABEL = 'registered-writers/v1';
31
- /**
32
- * The resource id of one writer's entry under one account: the first 16
33
- * bytes of `sha256(utf8('registered-writers/v1|' + accountDid + '|' +
34
- * writerId))`, formatted as an EDV document id.
35
- *
36
- * The id is deterministic, so a registration and a touch are idempotent
37
- * upserts. It hides the `writerId` from the storage host and does not link
38
- * one `writerId` across accounts.
39
- *
40
- * @param options {object}
41
- * @param options.accountDid {string} the account whose Space holds the roster
42
- * @param options.writerId {string}
43
- * @returns {string}
44
- */
45
- export function registeredWriterResourceId({ accountDid, writerId }) {
46
- const input = new TextEncoder().encode(`${REGISTERED_WRITER_ID_LABEL}|${accountDid}|${writerId}`);
47
- return edvIdFromBytes(sha256(input).subarray(0, 16));
48
- }
49
- /**
50
- * Resolves a partial policy override against the defaults.
51
- *
52
- * @param [policy] {Partial<RegisteredWriterPolicy>}
53
- * @returns {RegisteredWriterPolicy}
54
- */
55
- export function registeredWriterPolicy(policy) {
56
- return { ...REGISTERED_WRITER_POLICY, ...policy };
57
- }
58
- /**
59
- * Reads a stored body as a roster entry, or `undefined` when it is not one.
60
- * A malformed entry is skipped by every reader, and never repaired.
61
- *
62
- * @param body {unknown}
63
- * @returns {RegisteredWriterEntry | undefined}
64
- */
65
- export function parseRegisteredWriterEntry(body) {
66
- if (body === null || typeof body !== 'object') {
67
- return undefined;
68
- }
69
- const { version, writerId, signingKeyMultibase, label, lastSeen, active } = body;
70
- if (version !== 1 ||
71
- typeof writerId !== 'string' ||
72
- writerId === '' ||
73
- typeof label !== 'string' ||
74
- typeof lastSeen !== 'string' ||
75
- Number.isNaN(Date.parse(lastSeen)) ||
76
- typeof active !== 'boolean' ||
77
- (signingKeyMultibase !== undefined &&
78
- typeof signingKeyMultibase !== 'string')) {
79
- return undefined;
80
- }
81
- return {
82
- version: 1,
83
- writerId,
84
- ...(signingKeyMultibase !== undefined && { signingKeyMultibase }),
85
- label,
86
- lastSeen,
87
- active
88
- };
89
- }
90
- //# sourceMappingURL=entry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/writers/entry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;GASG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAuD/D,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAElC;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA2B;IAC9D,eAAe,EAAE,EAAE,GAAG,MAAM;IAC5B,UAAU,EAAE,EAAE;IACd,eAAe,EAAE,MAAM;CACxB,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,uBAAuB,CAAA;AAEjE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,0BAA0B,CAAC,EACzC,UAAU,EACV,QAAQ,EAIT;IACC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CACpC,GAAG,0BAA0B,IAAI,UAAU,IAAI,QAAQ,EAAE,CAC1D,CAAA;IACD,OAAO,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAwC;IAExC,OAAO,EAAE,GAAG,wBAAwB,EAAE,GAAG,MAAM,EAAE,CAAA;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CACxC,IAAa;IAEb,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9C,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,GACvE,IAA+B,CAAA;IACjC,IACE,OAAO,KAAK,CAAC;QACb,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,KAAK,EAAE;QACf,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,QAAQ,KAAK,QAAQ;QAC5B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,MAAM,KAAK,SAAS;QAC3B,CAAC,mBAAmB,KAAK,SAAS;YAChC,OAAO,mBAAmB,KAAK,QAAQ,CAAC,EAC1C,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO;QACL,OAAO,EAAE,CAAC;QACV,QAAQ;QACR,GAAG,CAAC,mBAAmB,KAAK,SAAS,IAAI,EAAE,mBAAmB,EAAE,CAAC;QACjE,KAAK;QACL,QAAQ;QACR,MAAM;KACP,CAAA;AACH,CAAC"}
@@ -1,17 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * The writer roster: the `registered-writers` collection's entry shape, its
6
- * resource id, the storage seam and WAS adapter, lazy registration with the
7
- * throttled liveness touch, the sweep-on-read with two-phase expiry, and the
8
- * join a history view resolves a revision's `writerId` through. Every field
9
- * is advisory display data, and none is an input to any decision.
10
- */
11
- export { REGISTERED_WRITER_ID_LABEL, REGISTERED_WRITER_POLICY, parseRegisteredWriterEntry, registeredWriterPolicy, registeredWriterResourceId } from './entry.js';
12
- export type { RegisteredWriterEntry, RegisteredWriterPolicy } from './entry.js';
13
- export { wasRegisteredWritersStore } from './store.js';
14
- export type { RegisteredWritersStore, StoredRegisteredWriter } from './store.js';
15
- export { registerWriterOnSecondSession, renameRegisteredWriter, resolveRegisteredWriter, sweepRegisteredWriters } from './roster.js';
16
- export type { RegisteredWritersSweep, ResolvedWriter, WriterRegistrationOutcome, WriterFirstSeenRecord, WriterFirstSeenStore } from './roster.js';
17
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/writers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC3B,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAA;AACtD,YAAY,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAChF,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,aAAa,CAAA"}
@@ -1,14 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * The writer roster: the `registered-writers` collection's entry shape, its
6
- * resource id, the storage seam and WAS adapter, lazy registration with the
7
- * throttled liveness touch, the sweep-on-read with two-phase expiry, and the
8
- * join a history view resolves a revision's `writerId` through. Every field
9
- * is advisory display data, and none is an input to any decision.
10
- */
11
- export { REGISTERED_WRITER_ID_LABEL, REGISTERED_WRITER_POLICY, parseRegisteredWriterEntry, registeredWriterPolicy, registeredWriterResourceId } from './entry.js';
12
- export { wasRegisteredWritersStore } from './store.js';
13
- export { registerWriterOnSecondSession, renameRegisteredWriter, resolveRegisteredWriter, sweepRegisteredWriters } from './roster.js';
14
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/writers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC3B,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAA;AAEtD,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,aAAa,CAAA"}
@@ -1,152 +0,0 @@
1
- import type { RegisteredWriterEntry, RegisteredWriterPolicy } from './entry.js';
2
- import type { RegisteredWritersStore } from './store.js';
3
- /**
4
- * The writer first-seen record, kept client-local: the account and
5
- * `writerId` this client's writer first appeared under, and when it last
6
- * touched its roster entry. One slot, so a writer that moves to another
7
- * account starts over.
8
- */
9
- export interface WriterFirstSeenRecord {
10
- accountDid: string;
11
- writerId: string;
12
- /**
13
- * ISO 8601 UTC start of the session the record was written in.
14
- */
15
- firstSessionAt: string;
16
- /**
17
- * ISO 8601 UTC time of the latest successful registration or touch.
18
- */
19
- lastTouchedAt?: string;
20
- }
21
- /**
22
- * The client-local seam for the writer first-seen record. Where it lives is
23
- * the wallet's choice. A forget of this client's local state clears it along with
24
- * the `writerId`.
25
- */
26
- export interface WriterFirstSeenStore {
27
- get(): Promise<unknown>;
28
- put(record: WriterFirstSeenRecord): Promise<void>;
29
- }
30
- /**
31
- * What {@link registerWriterOnSecondSession} did.
32
- *
33
- * - `deferred` -- the writer has not yet been encountered in a second session
34
- * under this account; the first-seen record is (re)written and the roster
35
- * is untouched.
36
- * - `fresh` -- the latest touch is within the touch interval; no I/O.
37
- * - `registered` -- a new entry was written (or a malformed one replaced).
38
- * - `touched` -- the existing entry's `lastSeen` was advanced.
39
- * - `raced` -- every attempt lost a conditional write; the next call retries.
40
- */
41
- export type WriterRegistrationOutcome = 'deferred' | 'fresh' | 'registered' | 'touched' | 'raced';
42
- /**
43
- * Registers this client's writer in the roster once it is encountered in a
44
- * second session under the account, and touches its `lastSeen` at most once
45
- * per touch interval after that. Call it on the wallet's connect or sync path;
46
- * calls within the interval cost no I/O.
47
- *
48
- * A new entry takes `label`. A touch keeps the stored label, so a rename
49
- * stands, and refreshes `signingKeyMultibase` when one is given. Registering
50
- * a new entry first makes room under the entry cap, deleting the
51
- * oldest-`lastSeen` entries.
52
- *
53
- * @param options {object}
54
- * @param options.store {RegisteredWritersStore}
55
- * @param options.local {WriterFirstSeenStore}
56
- * @param options.accountDid {string} the account whose Space holds the roster
57
- * @param options.writerId {string} this client's writer
58
- * @param options.label {string} the coarse platform self-description a new
59
- * entry takes
60
- * @param options.sessionStartedAt {Date} when the current session began; a
61
- * first-seen record written at or after it is this session's own
62
- * @param [options.signingKeyMultibase] {string} an enrolled wallet client's
63
- * own signing-key multibase
64
- * @param [options.now] {Date}
65
- * @param [options.policy] {Partial<RegisteredWriterPolicy>}
66
- * @returns {Promise<WriterRegistrationOutcome>}
67
- */
68
- export declare function registerWriterOnSecondSession({ store, local, accountDid, writerId, label, sessionStartedAt, signingKeyMultibase, now, policy }: {
69
- store: RegisteredWritersStore;
70
- local: WriterFirstSeenStore;
71
- accountDid: string;
72
- writerId: string;
73
- label: string;
74
- sessionStartedAt: Date;
75
- signingKeyMultibase?: string;
76
- now?: Date;
77
- policy?: Partial<RegisteredWriterPolicy>;
78
- }): Promise<WriterRegistrationOutcome>;
79
- /**
80
- * Renames this client's writer. The rename lands only on a registered entry;
81
- * before registration there is nothing to rename, and the call returns
82
- * `false`.
83
- *
84
- * @param options {object}
85
- * @param options.store {RegisteredWritersStore}
86
- * @param options.accountDid {string}
87
- * @param options.writerId {string}
88
- * @param options.label {string} the new label; blank is refused
89
- * @returns {Promise<boolean>} whether an entry was renamed
90
- */
91
- export declare function renameRegisteredWriter({ store, accountDid, writerId, label }: {
92
- store: RegisteredWritersStore;
93
- accountDid: string;
94
- writerId: string;
95
- label: string;
96
- }): Promise<boolean>;
97
- /**
98
- * The outcome of a sweep: the entries left standing, and what it changed.
99
- */
100
- export interface RegisteredWritersSweep {
101
- entries: RegisteredWriterEntry[];
102
- markedInactive: string[];
103
- deleted: string[];
104
- }
105
- /**
106
- * Reads the roster and sweeps it: the sweep-on-read every history view runs.
107
- * Safe to run from any replica, and concurrently.
108
- *
109
- * @param options {object}
110
- * @param options.store {RegisteredWritersStore}
111
- * @param options.accountDid {string} the account whose Space holds the roster
112
- * @param [options.now] {Date}
113
- * @param [options.policy] {Partial<RegisteredWriterPolicy>}
114
- * @returns {Promise<RegisteredWritersSweep>}
115
- */
116
- export declare function sweepRegisteredWriters({ store, accountDid, now, policy }: {
117
- store: RegisteredWritersStore;
118
- accountDid: string;
119
- now?: Date;
120
- policy?: Partial<RegisteredWriterPolicy>;
121
- }): Promise<RegisteredWritersSweep>;
122
- /**
123
- * How a history view renders one revision's writer. `undefined` from
124
- * {@link resolveRegisteredWriter} means no entry: the view renders its
125
- * fallback label ("another session").
126
- */
127
- export interface ResolvedWriter {
128
- label: string;
129
- active: boolean;
130
- /**
131
- * Present only when the entry's `signingKeyMultibase` is an enrolled
132
- * client's key in the verified account document. The view may then link
133
- * the revision to that client's row. Absent, the label stands unlinked.
134
- */
135
- clientSigningKeyMultibase?: string;
136
- }
137
- /**
138
- * Resolves a revision's `writerId` against the swept roster.
139
- *
140
- * @param options {object}
141
- * @param options.writerId {string}
142
- * @param options.entries {RegisteredWriterEntry[]} a sweep's `entries`
143
- * @param options.enrolledSigningKeys {ReadonlySet<string>} the signing-key
144
- * multibases of the enrolled clients in the verified account document
145
- * @returns {ResolvedWriter | undefined}
146
- */
147
- export declare function resolveRegisteredWriter({ writerId, entries, enrolledSigningKeys }: {
148
- writerId: string;
149
- entries: RegisteredWriterEntry[];
150
- enrolledSigningKeys: ReadonlySet<string>;
151
- }): ResolvedWriter | undefined;
152
- //# sourceMappingURL=roster.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"roster.d.ts","sourceRoot":"","sources":["../../src/writers/roster.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAA0B,MAAM,YAAY,CAAA;AAEhF;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACvB,GAAG,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClD;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,yBAAyB,GACnC,UAAU,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAA;AAyI3D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,6BAA6B,CAAC,EAClD,KAAK,EACL,KAAK,EACL,UAAU,EACV,QAAQ,EACR,KAAK,EACL,gBAAgB,EAChB,mBAAmB,EACnB,GAAgB,EAChB,MAAM,EACP,EAAE;IACD,KAAK,EAAE,sBAAsB,CAAA;IAC7B,KAAK,EAAE,oBAAoB,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,IAAI,CAAA;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;CACzC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CA0ErC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,KAAK,EACL,UAAU,EACV,QAAQ,EACR,KAAK,EACN,EAAE;IACD,KAAK,EAAE,sBAAsB,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBnB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,qBAAqB,EAAE,CAAA;IAChC,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAiGD;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,KAAK,EACL,UAAU,EACV,GAAgB,EAChB,MAAM,EACP,EAAE;IACD,KAAK,EAAE,sBAAsB,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAA;CACzC,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAUlC;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,OAAO,EACP,mBAAmB,EACpB,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,qBAAqB,EAAE,CAAA;IAChC,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACzC,GAAG,cAAc,GAAG,SAAS,CAa7B"}