@plane31/blind-relay 0.0.0-stage → 0.1.1

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 (135) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +26 -2
  3. package/dist/adapters/index.d.ts +18 -0
  4. package/dist/adapters/index.d.ts.map +1 -0
  5. package/dist/adapters/index.js +22 -0
  6. package/dist/adapters/index.js.map +1 -0
  7. package/dist/audience.d.ts +77 -0
  8. package/dist/audience.d.ts.map +1 -0
  9. package/dist/audience.js +76 -0
  10. package/dist/audience.js.map +1 -0
  11. package/dist/bytes.d.ts +54 -0
  12. package/dist/bytes.d.ts.map +1 -0
  13. package/dist/bytes.js +200 -0
  14. package/dist/bytes.js.map +1 -0
  15. package/dist/circle.d.ts +59 -0
  16. package/dist/circle.d.ts.map +1 -0
  17. package/dist/circle.js +105 -0
  18. package/dist/circle.js.map +1 -0
  19. package/dist/client.d.ts +234 -0
  20. package/dist/client.d.ts.map +1 -0
  21. package/dist/client.js +1365 -0
  22. package/dist/client.js.map +1 -0
  23. package/dist/codec.d.ts +189 -0
  24. package/dist/codec.d.ts.map +1 -0
  25. package/dist/codec.js +512 -0
  26. package/dist/codec.js.map +1 -0
  27. package/dist/crypto/backend.d.ts +39 -0
  28. package/dist/crypto/backend.d.ts.map +1 -0
  29. package/dist/crypto/backend.js +8 -0
  30. package/dist/crypto/backend.js.map +1 -0
  31. package/dist/crypto/noble.d.ts +3 -0
  32. package/dist/crypto/noble.d.ts.map +1 -0
  33. package/dist/crypto/noble.js +107 -0
  34. package/dist/crypto/noble.js.map +1 -0
  35. package/dist/crypto/sodium.d.ts +7 -0
  36. package/dist/crypto/sodium.d.ts.map +1 -0
  37. package/dist/crypto/sodium.js +39 -0
  38. package/dist/crypto/sodium.js.map +1 -0
  39. package/dist/crypto.d.ts +66 -0
  40. package/dist/crypto.d.ts.map +1 -0
  41. package/dist/crypto.js +225 -0
  42. package/dist/crypto.js.map +1 -0
  43. package/dist/epoch.d.ts +93 -0
  44. package/dist/epoch.d.ts.map +1 -0
  45. package/dist/epoch.js +121 -0
  46. package/dist/epoch.js.map +1 -0
  47. package/dist/errors.d.ts +17 -0
  48. package/dist/errors.d.ts.map +1 -0
  49. package/dist/errors.js +30 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/historyIndex.d.ts +15 -0
  52. package/dist/historyIndex.d.ts.map +1 -0
  53. package/dist/historyIndex.js +57 -0
  54. package/dist/historyIndex.js.map +1 -0
  55. package/dist/identity.d.ts +62 -0
  56. package/dist/identity.d.ts.map +1 -0
  57. package/dist/identity.js +99 -0
  58. package/dist/identity.js.map +1 -0
  59. package/dist/inbox.d.ts +153 -0
  60. package/dist/inbox.d.ts.map +1 -0
  61. package/dist/inbox.js +472 -0
  62. package/dist/inbox.js.map +1 -0
  63. package/dist/index.d.ts +19 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +22 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/outbox.d.ts +96 -0
  68. package/dist/outbox.d.ts.map +1 -0
  69. package/dist/outbox.js +339 -0
  70. package/dist/outbox.js.map +1 -0
  71. package/dist/policy.d.ts +33 -0
  72. package/dist/policy.d.ts.map +1 -0
  73. package/dist/policy.js +71 -0
  74. package/dist/policy.js.map +1 -0
  75. package/dist/record.d.ts +49 -0
  76. package/dist/record.d.ts.map +1 -0
  77. package/dist/record.js +46 -0
  78. package/dist/record.js.map +1 -0
  79. package/dist/reset.d.ts +74 -0
  80. package/dist/reset.d.ts.map +1 -0
  81. package/dist/reset.js +127 -0
  82. package/dist/reset.js.map +1 -0
  83. package/dist/rows.d.ts +16 -0
  84. package/dist/rows.d.ts.map +1 -0
  85. package/dist/rows.js +103 -0
  86. package/dist/rows.js.map +1 -0
  87. package/dist/slots.d.ts +22 -0
  88. package/dist/slots.d.ts.map +1 -0
  89. package/dist/slots.js +38 -0
  90. package/dist/slots.js.map +1 -0
  91. package/dist/store.d.ts +357 -0
  92. package/dist/store.d.ts.map +1 -0
  93. package/dist/store.js +192 -0
  94. package/dist/store.js.map +1 -0
  95. package/dist/testing/clock.d.ts +14 -0
  96. package/dist/testing/clock.d.ts.map +1 -0
  97. package/dist/testing/clock.js +27 -0
  98. package/dist/testing/clock.js.map +1 -0
  99. package/dist/testing/fakeHost.d.ts +118 -0
  100. package/dist/testing/fakeHost.d.ts.map +1 -0
  101. package/dist/testing/fakeHost.js +462 -0
  102. package/dist/testing/fakeHost.js.map +1 -0
  103. package/dist/testing/faults.d.ts +97 -0
  104. package/dist/testing/faults.d.ts.map +1 -0
  105. package/dist/testing/faults.js +264 -0
  106. package/dist/testing/faults.js.map +1 -0
  107. package/dist/testing/fixtures.d.ts +15 -0
  108. package/dist/testing/fixtures.d.ts.map +1 -0
  109. package/dist/testing/fixtures.js +22 -0
  110. package/dist/testing/fixtures.js.map +1 -0
  111. package/dist/testing/index.d.ts +7 -0
  112. package/dist/testing/index.d.ts.map +1 -0
  113. package/dist/testing/index.js +7 -0
  114. package/dist/testing/index.js.map +1 -0
  115. package/dist/testing/providers.d.ts +16 -0
  116. package/dist/testing/providers.d.ts.map +1 -0
  117. package/dist/testing/providers.js +36 -0
  118. package/dist/testing/providers.js.map +1 -0
  119. package/dist/testing/sweep.d.ts +46 -0
  120. package/dist/testing/sweep.d.ts.map +1 -0
  121. package/dist/testing/sweep.js +366 -0
  122. package/dist/testing/sweep.js.map +1 -0
  123. package/dist/transactions.d.ts +75 -0
  124. package/dist/transactions.d.ts.map +1 -0
  125. package/dist/transactions.js +212 -0
  126. package/dist/transactions.js.map +1 -0
  127. package/dist/transport.d.ts +125 -0
  128. package/dist/transport.d.ts.map +1 -0
  129. package/dist/transport.js +6 -0
  130. package/dist/transport.js.map +1 -0
  131. package/dist/vault.d.ts +59 -0
  132. package/dist/vault.d.ts.map +1 -0
  133. package/dist/vault.js +69 -0
  134. package/dist/vault.js.map +1 -0
  135. package/package.json +66 -3
package/dist/inbox.js ADDED
@@ -0,0 +1,472 @@
1
+ /**
2
+ * The receiver: records, history, the acknowledged prefix and the live pin
3
+ * (protocol section 10, receiving; transaction T7).
4
+ */
5
+ import { equalBytes, fromHex, toHex } from "./bytes.js";
6
+ import { DocumentType, expectType, parseDocument } from "./codec.js";
7
+ import { bodyHash } from "./crypto.js";
8
+ import { openEpoch } from "./epoch.js";
9
+ import { KavachError, isKavachError } from "./errors.js";
10
+ import { authorPrefix, indexHistory, padTime, timelinePrefix, unindexHistory } from "./historyIndex.js";
11
+ import { historyKinds, kindOf } from "./policy.js";
12
+ import { openRecordWire } from "./record.js";
13
+ import { big, unbig } from "./rows.js";
14
+ import { clampEventTime, slotKey, takeSlot } from "./slots.js";
15
+ export const MAX_FUTURE_SKEW_MS = 300000n;
16
+ export const READ_BATCH = 100;
17
+ // Views over the store --------------------------------------------------------------------------
18
+ function authorViewFor(tx, streamId) {
19
+ const certs = tx.list("certificates").filter(([, c]) => c.streamId === toHex(streamId));
20
+ const first = certs[0]?.[1];
21
+ if (!first)
22
+ return undefined;
23
+ const all = tx.list("certificates").filter(([, c]) => c.identityId === first.identityId);
24
+ const certificates = new Map(all.map(([, c]) => [c.certificateHash, { certificateHash: fromHex(c.certificateHash), signingKey: fromHex(c.signingKey), streamId: fromHex(c.streamId), current: c.current }]));
25
+ return { view: { identityId: fromHex(first.identityId), certificates }, identityId: fromHex(first.identityId) };
26
+ }
27
+ function isAuthorized(tx, authorIdentityId, self) {
28
+ if (equalBytes(authorIdentityId, self))
29
+ return true;
30
+ const hex = toHex(authorIdentityId);
31
+ return tx.list("circles").some(([, c]) => c.status === "member" && c.members.includes(hex));
32
+ }
33
+ function epochKeyFor(tx, streamId, epoch) {
34
+ const row = tx.get("readerEpochs", `${toHex(streamId)}:${epoch}`);
35
+ return row ? fromHex(row.epochKey) : undefined;
36
+ }
37
+ /** Fetch and verify an epoch's key through the relay and store it. Returns false when it cannot be had yet. */
38
+ async function fetchEpochKey(deps, streamId, epoch) {
39
+ let bundle;
40
+ try {
41
+ bundle = await deps.relay.getEpoch(streamId, epoch);
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ if (!bundle?.wrap)
47
+ return false;
48
+ const wrap = bundle.wrap;
49
+ const self = deps.self();
50
+ return deps.store.transaction((tx) => {
51
+ const author = authorViewFor(tx, streamId);
52
+ if (!author)
53
+ return false;
54
+ const opened = openEpoch(bundle.manifest, author.view, self, wrap); // throws the section 8 codes
55
+ tx.put("readerEpochs", `${toHex(streamId)}:${epoch}`, {
56
+ streamId: toHex(streamId),
57
+ epoch,
58
+ epochKey: toHex(opened.epochKey),
59
+ manifestHash: toHex(opened.manifest.bodyHash),
60
+ authorCertificateHash: toHex(opened.manifest.authorCertificateHash),
61
+ superseded: opened.superseded
62
+ });
63
+ return true;
64
+ });
65
+ }
66
+ // T7 -------------------------------------------------------------------------------------------------
67
+ /**
68
+ * Verify, decrypt and store one record (T7). Replays are harmless upserts; a different valid
69
+ * body for a retained id is `EQUIVOCATION`. The live pin moves only for kind 0 from the author's
70
+ * current device and a greater (generation, epoch, counter).
71
+ */
72
+ function storeRecord(tx, deps, wire, now) {
73
+ const self = deps.self();
74
+ const parsed = expectType(parseDocument(wire), DocumentType.EncryptedRecord, "receive");
75
+ if (parsed.sentAt > now + MAX_FUTURE_SKEW_MS)
76
+ return { result: "expired", reason: "CLOCK_SKEW" };
77
+ const author = authorViewFor(tx, parsed.streamId);
78
+ if (!author)
79
+ return { result: "invalid", reason: "NOT_AUTHORIZED" };
80
+ if (!isAuthorized(tx, author.identityId, self.identityId))
81
+ return { result: "invalid", reason: "NOT_AUTHORIZED" };
82
+ let opened;
83
+ try {
84
+ opened = openRecordWire(wire, author.view, (s, e) => epochKeyFor(tx, s, e));
85
+ }
86
+ catch (e) {
87
+ if (isKavachError(e, "KEY_PENDING"))
88
+ return { result: "keyPending", streamId: parsed.streamId, epoch: parsed.epoch };
89
+ if (e instanceof KavachError)
90
+ return { result: "invalid", reason: e.code };
91
+ throw e;
92
+ }
93
+ const id = toHex(opened.recordId);
94
+ const hash = toHex(bodyHash(opened.record.body));
95
+ const cert = [...author.view.certificates.values()].find((c) => equalBytes(c.streamId, parsed.streamId));
96
+ const generation = unbig(tx.list("certificates").find(([, c]) => c.streamId === toHex(parsed.streamId))?.[1].generation ?? "0");
97
+ const kind = opened.kind;
98
+ const base = { recordId: opened.recordId, authorIdentityId: author.identityId, kind };
99
+ const declared = kindOf(deps.policy, kind);
100
+ if (!declared)
101
+ return { result: "invalid", reason: "BAD_PAYLOAD" }; // a kind this product did not declare
102
+ const authorHex = toHex(author.identityId);
103
+ const fromCurrentDevice = !opened.superseded && !!cert?.current;
104
+ const candidate = { generation, eventTime: clampEventTime(opened.eventTime, parsed.sentAt), epoch: parsed.epoch, counter: parsed.counter, recordId: id, bodyHash: hash, sentAt: parsed.sentAt, receivedAt: now, payload: opened.payload };
105
+ if (!declared.history) {
106
+ // A slot-only kind is the author's current state, not an event: one row per author, the newest
107
+ // from the current device wins. An older or superseded one changes nothing.
108
+ const current = tx.get("newest", slotKey(authorHex, kind));
109
+ if (current?.recordId === id) {
110
+ if (current.bodyHash === hash)
111
+ return { result: "duplicate", recordId: opened.recordId };
112
+ return { result: "invalid", reason: "EQUIVOCATION" };
113
+ }
114
+ if (!fromCurrentDevice)
115
+ return { result: "older", ...base };
116
+ return takeSlot(tx, authorHex, kind, candidate, toHex) ? { result: "updated", ...base } : { result: "older", ...base };
117
+ }
118
+ const existing = tx.get("history", id);
119
+ if (existing) {
120
+ if (existing.bodyHash === hash)
121
+ return { result: "duplicate", recordId: opened.recordId };
122
+ return { result: "invalid", reason: "EQUIVOCATION" };
123
+ }
124
+ const row = {
125
+ recordId: id,
126
+ authorIdentityId: toHex(author.identityId),
127
+ streamId: toHex(parsed.streamId),
128
+ generation: big(generation),
129
+ epoch: parsed.epoch,
130
+ counter: parsed.counter,
131
+ kind,
132
+ sentAt: big(parsed.sentAt),
133
+ receivedAt: big(now),
134
+ plaintext: toHex(opened.payload),
135
+ superseded: opened.superseded || !cert?.current,
136
+ own: false,
137
+ bodyHash: hash,
138
+ ...(opened.eventTime === undefined ? {} : { eventTime: big(opened.eventTime) })
139
+ };
140
+ tx.put("history", id, row);
141
+ indexHistory(tx, row);
142
+ // A kind with a slot is news when it takes the slot; a kind without one is news every time.
143
+ const took = declared.newest && fromCurrentDevice ? takeSlot(tx, authorHex, kind, candidate, toHex) : false;
144
+ return took || !declared.newest ? { result: "updated", ...base } : { result: "history", ...base };
145
+ }
146
+ /** A record pushed by the host outside `sync`: stored, but it never advances a relay cursor. */
147
+ export async function receive(deps, wire) {
148
+ const now = deps.now();
149
+ let r = await deps.store.transaction((tx) => storeRecord(tx, deps, wire, now));
150
+ if (r.result === "keyPending" && (await fetchEpochKey(deps, r.streamId, r.epoch).catch(() => false))) {
151
+ r = await deps.store.transaction((tx) => storeRecord(tx, deps, wire, now));
152
+ }
153
+ if (r.result === "invalid" && r.reason === "EQUIVOCATION")
154
+ deps.events?.securityError?.("EQUIVOCATION", "a different valid body for a retained record id");
155
+ deps.events?.received?.(r);
156
+ return r;
157
+ }
158
+ function subscription(tx, streamId, authorIdentityId) {
159
+ return (tx.get("subscriptions", toHex(streamId)) ?? {
160
+ streamId: toHex(streamId),
161
+ authorIdentityId: toHex(authorIdentityId),
162
+ scanPos: "0",
163
+ ackPrefix: "0",
164
+ committedCursor: "0",
165
+ ackInFlight: false
166
+ });
167
+ }
168
+ /** The eligible prefix: the scan position, held back to just before the oldest unresolved sequence. */
169
+ function eligiblePrefix(tx, streamId, scanPos, expiredThrough) {
170
+ let prefix = scanPos;
171
+ for (const [, u] of tx.list("unresolved", toHex(streamId) + ":")) {
172
+ const seq = unbig(u.deliverySeq);
173
+ if (seq <= expiredThrough)
174
+ continue; // the relay expired it: queue progress, never a receipt
175
+ if (seq - 1n < prefix)
176
+ prefix = seq - 1n;
177
+ }
178
+ return prefix;
179
+ }
180
+ /**
181
+ * Read a stream in pages until it is caught up or the budget is spent. The first page restarts
182
+ * from the eligible prefix while a record is unresolved (the held record is read again; stored
183
+ * ones come back as harmless duplicates); later pages of the same sync continue from the last
184
+ * sequence examined, so a held record never makes the loop re-read its own page. Each page is
185
+ * processed and acknowledged before the next is read. `hasMore` says the relay still holds
186
+ * records past the last page when the budget stopped the loop.
187
+ */
188
+ export async function syncStream(deps, streamId, authorIdentityId, budget = { remainingRecords: READ_BATCH, deadline: deps.now() }) {
189
+ const summary = { read: 0, stored: 0, duplicate: 0, keyPending: 0, invalid: 0, expired: 0, acked: undefined, hasMore: false };
190
+ const sub = await deps.store.read((tx) => subscription(tx, streamId, authorIdentityId));
191
+ const unresolved = await deps.store.read((tx) => tx.list("unresolved", toHex(streamId) + ":"));
192
+ let from = unresolved.length > 0 ? unbig(sub.ackPrefix) : unbig(sub.scanPos);
193
+ for (;;) {
194
+ // A failed read is the caller's to report: the sync names the stream in its report and goes
195
+ // on to the next one, rather than counting a stream it never read as synced.
196
+ const page = await deps.relay.readRecords(streamId, from, READ_BATCH);
197
+ await processPage(deps, streamId, authorIdentityId, page, summary);
198
+ budget.remainingRecords -= page.records.length;
199
+ const caughtUp = page.nextSeq >= page.tail || page.nextSeq <= from;
200
+ if (caughtUp)
201
+ break;
202
+ if (budget.remainingRecords <= 0 || deps.now() >= budget.deadline) {
203
+ summary.hasMore = true;
204
+ break;
205
+ }
206
+ from = page.nextSeq;
207
+ }
208
+ return summary;
209
+ }
210
+ /** T7 for every record of one page, then the scan position, the eligible prefix and one acknowledgement. */
211
+ async function processPage(deps, streamId, authorIdentityId, page, summary) {
212
+ const now = deps.now();
213
+ // Drop unresolved entries the relay has expired.
214
+ for (const [key, u] of await deps.store.read((tx) => tx.list("unresolved", toHex(streamId) + ":"))) {
215
+ if (unbig(u.deliverySeq) <= page.expiredThrough) {
216
+ await deps.store.transaction((tx) => tx.delete("unresolved", key));
217
+ summary.expired++;
218
+ }
219
+ }
220
+ for (const item of page.records) {
221
+ summary.read++;
222
+ if (item.deliverySeq <= page.expiredThrough) {
223
+ summary.expired++;
224
+ continue;
225
+ }
226
+ let r = await deps.store.transaction((tx) => storeRecord(tx, deps, item.wire, now));
227
+ if (r.result === "keyPending") {
228
+ let fetched = false;
229
+ try {
230
+ fetched = await fetchEpochKey(deps, r.streamId, r.epoch);
231
+ }
232
+ catch (e) {
233
+ if (isKavachError(e, "NOT_AUTHORIZED"))
234
+ r = { result: "invalid", reason: "NOT_AUTHORIZED" };
235
+ else if (e instanceof KavachError) {
236
+ // The served manifest or wrap did not verify. The record may still be honest, so it is
237
+ // held as keyPending (the prefix stops here, scenario 21) and the code is named; the
238
+ // relay's expiry resolves a manifest that never verifies.
239
+ deps.events?.securityError?.(e.code, `epoch ${r.epoch} of stream ${toHex(r.streamId).slice(0, 8)} refused`);
240
+ }
241
+ else
242
+ throw e;
243
+ }
244
+ if (fetched)
245
+ r = await deps.store.transaction((tx) => storeRecord(tx, deps, item.wire, now));
246
+ }
247
+ const seqKey = `${toHex(streamId)}:${item.deliverySeq.toString().padStart(20, "0")}`;
248
+ await deps.store.transaction((tx) => {
249
+ if (r.result === "keyPending") {
250
+ tx.put("unresolved", seqKey, { streamId: toHex(streamId), deliverySeq: big(item.deliverySeq), reason: "KEY_PENDING", epoch: r.epoch, recordedAt: big(now) });
251
+ }
252
+ else
253
+ tx.delete("unresolved", seqKey);
254
+ });
255
+ if (r.result === "keyPending") {
256
+ summary.keyPending++;
257
+ deps.events?.waiting?.(authorIdentityId);
258
+ }
259
+ else if (r.result === "invalid") {
260
+ // The relay serves only records addressed to this device, so anything unverifiable here is
261
+ // the host's or the author's doing: it is named to the app and never stored.
262
+ summary.invalid++;
263
+ deps.events?.securityError?.(r.reason, `record at sequence ${item.deliverySeq} refused`);
264
+ }
265
+ else if (r.result === "expired")
266
+ summary.expired++;
267
+ else if (r.result === "duplicate")
268
+ summary.duplicate++;
269
+ else
270
+ summary.stored++;
271
+ deps.events?.received?.(r);
272
+ }
273
+ // Advance the scan position and the eligible prefix; acknowledge once if it moved.
274
+ const toAck = await deps.store.transaction((tx) => {
275
+ const s = subscription(tx, streamId, authorIdentityId);
276
+ const scanPos = page.nextSeq > unbig(s.scanPos) ? page.nextSeq : unbig(s.scanPos);
277
+ const prefix = eligiblePrefix(tx, streamId, scanPos, page.expiredThrough);
278
+ const committed = page.committedCursor > unbig(s.committedCursor) ? page.committedCursor : unbig(s.committedCursor);
279
+ const next = { ...s, scanPos: big(scanPos), ackPrefix: big(prefix), committedCursor: big(committed) };
280
+ const send = prefix > committed && !s.ackInFlight;
281
+ tx.put("subscriptions", toHex(streamId), { ...next, ackInFlight: send });
282
+ return send ? prefix : undefined;
283
+ });
284
+ if (toAck !== undefined) {
285
+ let committed;
286
+ try {
287
+ const ack = await deps.relay.ackThrough(streamId, toAck);
288
+ if (ack.status === "COMMITTED")
289
+ committed = ack.committedCursor ?? toAck;
290
+ }
291
+ catch {
292
+ committed = undefined;
293
+ }
294
+ await deps.store.transaction((tx) => {
295
+ const s = subscription(tx, streamId, authorIdentityId);
296
+ tx.put("subscriptions", toHex(streamId), { ...s, ackInFlight: false, committedCursor: committed !== undefined && committed > unbig(s.committedCursor) ? big(committed) : s.committedCursor });
297
+ });
298
+ summary.acked = committed;
299
+ }
300
+ }
301
+ export const HISTORY_PAGE = 1000;
302
+ function toEntry(r) {
303
+ return {
304
+ recordId: fromHex(r.recordId),
305
+ authorIdentityId: fromHex(r.authorIdentityId),
306
+ kind: r.kind,
307
+ eventTime: r.eventTime === undefined ? undefined : unbig(r.eventTime),
308
+ sentAt: unbig(r.sentAt),
309
+ receivedAt: unbig(r.receivedAt),
310
+ plaintext: fromHex(r.plaintext),
311
+ superseded: r.superseded,
312
+ own: r.own
313
+ };
314
+ }
315
+ /** One page of history in time order, read through the index: one bounded scan per kind, merged. */
316
+ export async function historyPage(store, policy, q = {}) {
317
+ const limit = Math.max(0, Math.floor(q.limit ?? HISTORY_PAGE));
318
+ const reverse = q.order === "desc";
319
+ const all = historyKinds(policy);
320
+ const kinds = q.kind === undefined ? all : all.includes(q.kind) ? [q.kind] : [];
321
+ if (limit === 0 || kinds.length === 0)
322
+ return { entries: [], cursor: undefined };
323
+ return store.read((tx) => {
324
+ const scans = kinds.map((kind) => {
325
+ const prefix = q.authorIdentityId ? authorPrefix(toHex(q.authorIdentityId), kind) : timelinePrefix(kind);
326
+ // Bounds in tuple space, prefixed into key space: the lower end from `since` and an
327
+ // ascending cursor, the upper end from `before` and a descending cursor, the tighter winning.
328
+ const upper = [q.before === undefined ? undefined : padTime(q.before), reverse ? q.cursor : undefined].filter((b) => b !== undefined).sort()[0];
329
+ const range = {
330
+ prefix,
331
+ ...(q.since === undefined ? {} : { gte: prefix + padTime(q.since) }),
332
+ ...(!reverse && q.cursor !== undefined ? { gt: prefix + q.cursor } : {}),
333
+ ...(upper === undefined ? {} : { lt: prefix + upper }),
334
+ reverse,
335
+ limit
336
+ };
337
+ return tx.range("historyIndex", range).map(([key, r]) => ({ tuple: key.slice(prefix.length), recordId: r.recordId }));
338
+ });
339
+ const merged = mergeByTuple(scans, reverse, limit);
340
+ const entries = [];
341
+ for (const m of merged) {
342
+ const row = tx.get("history", m.recordId);
343
+ if (row)
344
+ entries.push(toEntry(row));
345
+ }
346
+ return { entries, cursor: merged.length === limit ? merged[merged.length - 1]?.tuple : undefined };
347
+ });
348
+ }
349
+ /** The first page only, for callers that want a plain list. */
350
+ export async function history(store, policy, q = {}) {
351
+ return (await historyPage(store, policy, q)).entries;
352
+ }
353
+ /** The newest history entry matching the filters, read as a one-entry descending page. */
354
+ export async function newest(store, policy, q = {}) {
355
+ return (await historyPage(store, policy, { ...q, order: "desc", limit: 1 })).entries[0];
356
+ }
357
+ /** Merge per-kind scans that are each in order into one ordered list of at most `limit`. */
358
+ function mergeByTuple(scans, reverse, limit) {
359
+ const heads = scans.map(() => 0);
360
+ const out = [];
361
+ while (out.length < limit) {
362
+ let pick;
363
+ for (let i = 0; i < scans.length; i++) {
364
+ const hit = scans[i]?.[heads[i] ?? 0];
365
+ if (!hit)
366
+ continue;
367
+ if (!pick || (reverse ? hit.tuple > pick.hit.tuple : hit.tuple < pick.hit.tuple))
368
+ pick = { i, hit };
369
+ }
370
+ if (!pick)
371
+ break;
372
+ out.push(pick.hit);
373
+ heads[pick.i] = (heads[pick.i] ?? 0) + 1;
374
+ }
375
+ return out;
376
+ }
377
+ /** The newest slot of an author and kind, or `undefined` when there is none or its payload expired (the slot stays, the payload is gone). */
378
+ export async function newestSlot(store, authorIdentityId, kind, now) {
379
+ return store.read((tx) => {
380
+ const row = tx.get("newest", slotKey(toHex(authorIdentityId), kind));
381
+ if (!row || row.payload === null)
382
+ return undefined;
383
+ return { recordId: fromHex(row.recordId), kind, payload: fromHex(row.payload), sentAt: unbig(row.sentAt), eventTime: unbig(row.eventTime), ageMs: now - unbig(row.sentAt) };
384
+ });
385
+ }
386
+ /**
387
+ * Build the slots once for a store written before the slot table: every non-superseded history
388
+ * row of a kind declared `newest` is offered to its slot in time order. A fresh store is marked
389
+ * at T1 and never runs this. Idempotent.
390
+ */
391
+ export async function ensureSlots(store, policy) {
392
+ const built = await store.read((tx) => tx.get("meta", "meta")?.newest === 1);
393
+ if (built)
394
+ return false;
395
+ return store.transaction((tx) => {
396
+ const meta = tx.get("meta", "meta");
397
+ if (!meta || meta.newest === 1)
398
+ return false;
399
+ for (const [, r] of tx.list("history")) {
400
+ if (r.superseded || !kindOf(policy, r.kind)?.newest)
401
+ continue;
402
+ const payload = fromHex(r.plaintext);
403
+ takeSlot(tx, r.authorIdentityId, r.kind, { generation: unbig(r.generation), eventTime: clampEventTime(r.eventTime === undefined ? undefined : unbig(r.eventTime), unbig(r.sentAt)), epoch: r.epoch, counter: r.counter, recordId: r.recordId, bodyHash: r.bodyHash ?? "", sentAt: unbig(r.sentAt), receivedAt: unbig(r.receivedAt), payload }, toHex);
404
+ }
405
+ tx.put("meta", "meta", { ...meta, newest: 1 });
406
+ return true;
407
+ });
408
+ }
409
+ /**
410
+ * Retention, per declared kind: drop history past the kind's window, and drop the payload of a
411
+ * newest slot past it while the row keeps its order, so an older record replayed later cannot
412
+ * become current.
413
+ */
414
+ export async function purgeHistory(store, policy, now) {
415
+ const window = (kind) => kindOf(policy, kind)?.retentionMs;
416
+ const kindOfSlot = (key) => Number(key.slice(key.lastIndexOf(":") + 1));
417
+ const staleSlot = (key, r) => {
418
+ const w = window(kindOfSlot(key));
419
+ return r.payload !== null && w !== undefined && unbig(r.sentAt) + w <= now;
420
+ };
421
+ // The expired prefix of each kind's timeline: `sentAt + window <= now`, as a key bound.
422
+ const expiredRange = (kind, limit) => {
423
+ const w = window(kind);
424
+ const cutoff = w === undefined ? 0n : now - w + 1n;
425
+ return cutoff <= 0n ? undefined : { prefix: timelinePrefix(kind), lt: timelinePrefix(kind) + padTime(cutoff), ...(limit === undefined ? {} : { limit }) };
426
+ };
427
+ const expired = (tx, limit) => historyKinds(policy).flatMap((kind) => {
428
+ const r = expiredRange(kind, limit);
429
+ return r ? tx.range("historyIndex", r) : [];
430
+ });
431
+ // Read first: most syncs purge nothing and must not take the writer lock for it.
432
+ const any = await store.read((tx) => expired(tx, 1).length > 0 || tx.list("newest").some(([k, r]) => staleSlot(k, r)));
433
+ if (!any)
434
+ return 0;
435
+ return store.transaction((tx) => {
436
+ let removed = 0;
437
+ for (const [key, hit] of expired(tx)) {
438
+ const row = tx.get("history", hit.recordId);
439
+ if (!row) {
440
+ tx.delete("historyIndex", key);
441
+ continue;
442
+ }
443
+ unindexHistory(tx, row);
444
+ tx.delete("history", hit.recordId);
445
+ removed++;
446
+ }
447
+ for (const [key, r] of tx.list("newest")) {
448
+ if (staleSlot(key, r)) {
449
+ tx.put("newest", key, { ...r, payload: null });
450
+ if (!kindOf(policy, kindOfSlot(key))?.history)
451
+ removed++; // a history kind's record was counted with its row
452
+ }
453
+ }
454
+ return removed;
455
+ });
456
+ }
457
+ /** Clear a removed author's newest slots and keys; history already received stays. */
458
+ export async function forgetAuthor(store, authorIdentityId) {
459
+ await store.transaction((tx) => forgetAuthorIn(tx, authorIdentityId));
460
+ }
461
+ /** The same, inside a caller's transaction. */
462
+ export function forgetAuthorIn(tx, authorIdentityId) {
463
+ for (const [k] of tx.list("newest", toHex(authorIdentityId) + ":"))
464
+ tx.delete("newest", k);
465
+ for (const [, c] of tx.list("certificates")) {
466
+ if (c.identityId !== toHex(authorIdentityId))
467
+ continue;
468
+ for (const [k] of tx.list("readerEpochs", c.streamId + ":"))
469
+ tx.delete("readerEpochs", k);
470
+ }
471
+ }
472
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @plane31/blind-relay: Kavach v1 protocol (revision 6, wire version 5).
3
+ *
4
+ * This entry is what an application imports: the client, its types, the errors and the few
5
+ * helpers an app needs around it. Adapter and host authors import `@plane31/blind-relay/adapters`;
6
+ * test harnesses import `@plane31/blind-relay/testing`; the optional libsodium backend is
7
+ * `@plane31/blind-relay/sodium`. Everything else is internal and reachable only by relative import.
8
+ */
9
+ export declare const PROTOCOL_NAME = "Kavach";
10
+ export declare const PROTOCOL_REVISION = 8;
11
+ export { open, type CircleSummary, type Client, type ClientEvent, type ClientState, type ClientStatus, type EnqueueOptions, type EnqueueResult, type HistoryEntry, type HistoryPage, type HistoryQuery, type Inspection, type Newest, type OpenOptions, type PauseReason, type ReceiveResult, type SyncError, type SyncOptions, type SyncReport } from "./client.js";
12
+ export { KavachError, isKavachError, type ErrorCode } from "./errors.js";
13
+ export type { RecordKind } from "./codec.js";
14
+ export { validatePolicy, type KindDeclaration, type RetentionPolicy } from "./policy.js";
15
+ export type { ResetTrustConfig } from "./reset.js";
16
+ export { setCryptoBackend, type CryptoBackend } from "./crypto.js";
17
+ export { decodeRecoveryCode, encodeRecoveryCode, type BackupState, type ProviderLoadResult, type ProviderSaveResult, type ProviderStatus, type ProviderStatusResult, type RecoveryProvider } from "./vault.js";
18
+ export { equalBytes, fromHex, toHex } from "./bytes.js";
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,WAAW,CAAC;AACtC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAGnC,OAAO,EACL,IAAI,EACJ,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAGzE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @plane31/blind-relay: Kavach v1 protocol (revision 6, wire version 5).
3
+ *
4
+ * This entry is what an application imports: the client, its types, the errors and the few
5
+ * helpers an app needs around it. Adapter and host authors import `@plane31/blind-relay/adapters`;
6
+ * test harnesses import `@plane31/blind-relay/testing`; the optional libsodium backend is
7
+ * `@plane31/blind-relay/sodium`. Everything else is internal and reachable only by relative import.
8
+ */
9
+ export const PROTOCOL_NAME = "Kavach";
10
+ export const PROTOCOL_REVISION = 8;
11
+ // The client ---------------------------------------------------------------------------------------
12
+ export { open } from "./client.js";
13
+ // Errors -------------------------------------------------------------------------------------------
14
+ export { KavachError, isKavachError } from "./errors.js";
15
+ // Configuration ------------------------------------------------------------------------------------
16
+ export { validatePolicy } from "./policy.js";
17
+ export { setCryptoBackend } from "./crypto.js";
18
+ // Recovery -----------------------------------------------------------------------------------------
19
+ export { decodeRecoveryCode, encodeRecoveryCode } from "./vault.js";
20
+ // Identifiers --------------------------------------------------------------------------------------
21
+ export { equalBytes, fromHex, toHex } from "./bytes.js";
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,QAAQ,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC,qGAAqG;AACrG,OAAO,EACL,IAAI,EAmBL,MAAM,aAAa,CAAC;AAErB,qGAAqG;AACrG,OAAO,EAAE,WAAW,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAKzE,qGAAqG;AACrG,OAAO,EAAE,cAAc,EAA8C,MAAM,aAAa,CAAC;AAEzF,OAAO,EAAE,gBAAgB,EAAsB,MAAM,aAAa,CAAC;AAEnE,qGAAqG;AACrG,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAOnB,MAAM,YAAY,CAAC;AAEpB,qGAAqG;AACrG,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}