@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/record.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Records: sealing with the active epoch, opening with certificate and manifest resolution
3
+ * (protocol section 9).
4
+ */
5
+ import { equalBytes, toHex } from "./bytes.js";
6
+ import { DocumentType, buildRecordWire, decodeEnvelope, expectType, openRecord as openRecordBody, parseDocument, verifyDocument } from "./codec.js";
7
+ import { NONCE_BYTES, randomBytes, recordId } from "./crypto.js";
8
+ import { MAX_COUNTER } from "./epoch.js";
9
+ import { KavachError } from "./errors.js";
10
+ /** Seal one record under the active epoch. The caller persists the result and the next counter (T6). */
11
+ export function sealRecord(input) {
12
+ if (input.nextCounter > MAX_COUNTER)
13
+ throw new KavachError("COUNTER_EXHAUSTED", "sealRecord");
14
+ const nonce = input.nonce ?? randomBytes(NONCE_BYTES);
15
+ const wire = buildRecordWire({ streamId: input.streamId, epoch: input.epoch, counter: input.nextCounter, sentAt: input.sentAt, headerClass: input.headerClass, kind: input.kind, eventTime: input.eventTime }, input.payload, input.epochKey, nonce, input.signingSecretKey);
16
+ return { wire, recordId: recordId(input.streamId, input.epoch, input.nextCounter), counter: input.nextCounter, kind: input.kind };
17
+ }
18
+ /**
19
+ * Verify and open a record. The author view supplies the certificate for the record's stream
20
+ * (the current one, or an archived one for history); `epochKeyFor` returns the stored key for
21
+ * (stream, epoch) or `undefined`, which is `KEY_PENDING`.
22
+ */
23
+ export function openRecordWire(wire, author, epochKeyFor) {
24
+ const stage = "openRecord";
25
+ const parsed = expectType(parseDocument(wire), DocumentType.EncryptedRecord, stage);
26
+ const cert = [...author.certificates.values()].find((c) => equalBytes(c.streamId, parsed.streamId));
27
+ if (!cert)
28
+ throw new KavachError("NOT_AUTHORIZED", stage, "record stream belongs to no known device of the author");
29
+ const record = expectType(verifyDocument(wire, cert.signingKey), DocumentType.EncryptedRecord, stage);
30
+ const key = epochKeyFor(record.streamId, record.epoch);
31
+ if (!key)
32
+ throw new KavachError("KEY_PENDING", stage, `no key for epoch ${record.epoch}`);
33
+ const envelope = decodeEnvelope(openRecordBody(record, key));
34
+ return { record, recordId: recordId(record.streamId, record.epoch, record.counter), kind: envelope.kind, eventTime: envelope.eventTime, payload: envelope.payload, superseded: !cert.current };
35
+ }
36
+ export function compareSlots(a, b) {
37
+ if (a.generation !== b.generation)
38
+ return a.generation < b.generation ? -1 : 1;
39
+ if (a.epoch !== b.epoch)
40
+ return a.epoch - b.epoch;
41
+ return a.counter - b.counter;
42
+ }
43
+ export function slotKey(streamId, epoch, counter) {
44
+ return `${toHex(streamId)}:${epoch}:${counter}`;
45
+ }
46
+ //# sourceMappingURL=record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { type AccountResetReceipt, type Parsed, type ResetKeyList } from "./codec.js";
2
+ export interface ResetTrustConfig {
3
+ /** The deployment's pinned management public key. */
4
+ readonly managementKey: Uint8Array;
5
+ /** The packaged minimum list version. */
6
+ readonly minimumVersion: bigint;
7
+ }
8
+ export interface ResetBinding {
9
+ readonly accountName: string;
10
+ readonly oldIdentityId: string;
11
+ readonly newIdentityId: string;
12
+ }
13
+ export interface ResetTrustState {
14
+ readonly current: {
15
+ wire: Uint8Array;
16
+ list: Parsed<ResetKeyList>;
17
+ } | undefined;
18
+ /** The greatest trusted time seen: a durable high-water mark. */
19
+ readonly timeHighWater: bigint;
20
+ readonly acceptedReceipts: ReadonlySet<string>;
21
+ readonly events: ReadonlyMap<string, ResetBinding>;
22
+ readonly retired: ReadonlySet<string>;
23
+ }
24
+ export declare const emptyResetTrust: ResetTrustState;
25
+ export type InstallOutcome = "INSTALLED" | "DUPLICATE";
26
+ export type ApplyOutcome = "ACCOUNT_KEY_CHANGED" | "DUPLICATE";
27
+ /** A peer's view of an accepted reset: who to stop sharing with, and whose circles close. */
28
+ export interface ResetEffect {
29
+ readonly outcome: ApplyOutcome;
30
+ readonly oldIdentityId: Uint8Array;
31
+ readonly newIdentityId: Uint8Array;
32
+ readonly receipt: Parsed<AccountResetReceipt>;
33
+ }
34
+ export declare class ResetTrust {
35
+ readonly config: ResetTrustConfig;
36
+ state: ResetTrustState;
37
+ constructor(config: ResetTrustConfig, state?: ResetTrustState);
38
+ /** The platform clock under the accurate-clock assumption, checked against the high-water mark. */
39
+ private clock;
40
+ /** Is the current list usable at `now`? */
41
+ fresh(now: bigint): boolean;
42
+ /**
43
+ * Install a key list: verified under the pinned management key, version at least the packaged
44
+ * minimum and the durable highest, equal version only with an equal body, fresh at `now`.
45
+ */
46
+ install(wire: Uint8Array, now: bigint | undefined): InstallOutcome;
47
+ /**
48
+ * Apply a reset receipt for an account whose current pinned identity is `currentIdentityId`.
49
+ * Requires a fresh list, an allowed signer, a verified new certificate and consistent bindings.
50
+ */
51
+ apply(receiptWire: Uint8Array, newCertificate: Uint8Array, accountName: string, currentIdentityId: Uint8Array, now: bigint | undefined): ResetEffect;
52
+ toRows(): ResetTrustRows;
53
+ static fromRows(config: ResetTrustConfig, rows: ResetTrustRows): ResetTrust;
54
+ }
55
+ export interface ResetTrustRows {
56
+ list: {
57
+ wire: string;
58
+ version: string;
59
+ hash: string;
60
+ checkedAt: string;
61
+ } | undefined;
62
+ clock: {
63
+ highWater: string;
64
+ };
65
+ accepted: string[];
66
+ events: {
67
+ resetId: string;
68
+ accountName: string;
69
+ oldIdentityId: string;
70
+ newIdentityId: string;
71
+ }[];
72
+ retired: string[];
73
+ }
74
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../src/reset.ts"],"names":[],"mappings":"AASA,OAAO,EAML,KAAK,mBAAmB,EACxB,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,yCAAyC;IACzC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;KAAE,GAAG,SAAS,CAAC;IAC/E,iEAAiE;IACjE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,eAAe,EAAE,eAA+H,CAAC;AAE9J,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,CAAC;AACvD,MAAM,MAAM,YAAY,GAAG,qBAAqB,GAAG,WAAW,CAAC;AAE/D,6FAA6F;AAC7F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,aAAa,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,mBAAmB,CAAC,CAAC;CAC/C;AAED,qBAAa,UAAU;IAEnB,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAC1B,KAAK,EAAE,eAAe;gBADpB,MAAM,EAAE,gBAAgB,EAC1B,KAAK,GAAE,eAAiC;IAGjD,mGAAmG;IACnG,OAAO,CAAC,KAAK;IAKb,2CAA2C;IAC3C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAK3B;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc;IAkBlE;;;OAGG;IACH,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW;IA6CpJ,MAAM,IAAI,cAAc;IAUxB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,GAAG,UAAU;CAU5E;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IACrF,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjG,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB"}
package/dist/reset.js ADDED
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Last-resort account reset and the reset keys (protocol section 12).
3
+ *
4
+ * `ResetTrust` is the acceptance model for management-signed key lists (type 8) and reset
5
+ * receipts (type 7): version rules, the 30-day lifetime, the trusted-clock rules with a durable
6
+ * time high-water mark, revocation by list, and immutable reset bindings. It is pure state with
7
+ * row conversions; the client persists it in T9. Nothing here pauses sharing.
8
+ */
9
+ import { equalBytes, fromHex, toHex } from "./bytes.js";
10
+ import { DocumentType, expectType, parseDocument, verifyDocument } from "./codec.js";
11
+ import { H, identityId } from "./crypto.js";
12
+ import { KavachError } from "./errors.js";
13
+ import { big, unbig } from "./rows.js";
14
+ export const emptyResetTrust = { current: undefined, timeHighWater: 0n, acceptedReceipts: new Set(), events: new Map(), retired: new Set() };
15
+ export class ResetTrust {
16
+ config;
17
+ state;
18
+ constructor(config, state = emptyResetTrust) {
19
+ this.config = config;
20
+ this.state = state;
21
+ }
22
+ /** The platform clock under the accurate-clock assumption, checked against the high-water mark. */
23
+ clock(now, stage) {
24
+ if (now === undefined || now < this.state.timeHighWater)
25
+ throw new KavachError("RESET_CLOCK_UNTRUSTED", stage);
26
+ return now;
27
+ }
28
+ /** Is the current list usable at `now`? */
29
+ fresh(now) {
30
+ const c = this.state.current;
31
+ return !!c && c.list.issuedAt <= now && now < c.list.expiresAt;
32
+ }
33
+ /**
34
+ * Install a key list: verified under the pinned management key, version at least the packaged
35
+ * minimum and the durable highest, equal version only with an equal body, fresh at `now`.
36
+ */
37
+ install(wire, now) {
38
+ const stage = "resetKeyList";
39
+ const list = expectType(verifyDocument(wire, this.config.managementKey), DocumentType.ResetKeyList, stage);
40
+ if (list.keys.some((k) => equalBytes(k.publicKey, this.config.managementKey))) {
41
+ throw new KavachError("INVALID_KEY", stage, "the management key cannot be an operational key");
42
+ }
43
+ const current = this.state.current;
44
+ if (list.version < this.config.minimumVersion || (current && list.version < current.list.version))
45
+ throw new KavachError("ROLLBACK", stage);
46
+ if (current && list.version === current.list.version && !equalBytes(list.bodyHash, current.list.bodyHash)) {
47
+ throw new KavachError("EQUIVOCATION", stage, "two key lists at one version");
48
+ }
49
+ const t = this.clock(now, stage);
50
+ if (!(list.issuedAt <= t && t < list.expiresAt))
51
+ throw new KavachError("RESET_KEYS_REQUIRED", stage, "list not fresh");
52
+ const outcome = current && list.version === current.list.version ? "DUPLICATE" : "INSTALLED";
53
+ this.state = { ...this.state, current: { wire, list }, timeHighWater: t };
54
+ return outcome;
55
+ }
56
+ /**
57
+ * Apply a reset receipt for an account whose current pinned identity is `currentIdentityId`.
58
+ * Requires a fresh list, an allowed signer, a verified new certificate and consistent bindings.
59
+ */
60
+ apply(receiptWire, newCertificate, accountName, currentIdentityId, now) {
61
+ const stage = "resetReceipt";
62
+ const parsed = expectType(parseDocument(receiptWire), DocumentType.AccountResetReceipt, stage);
63
+ const receiptHash = toHex(H(receiptWire));
64
+ if (this.state.acceptedReceipts.has(receiptHash)) {
65
+ return { outcome: "DUPLICATE", oldIdentityId: parsed.oldIdentityId, newIdentityId: parsed.newIdentityId, receipt: parsed };
66
+ }
67
+ const t = this.clock(now, stage);
68
+ if (!this.fresh(t))
69
+ throw new KavachError("RESET_KEYS_REQUIRED", stage, "no fresh key list");
70
+ const current = this.state.current;
71
+ if (!current)
72
+ throw new KavachError("RESET_KEYS_REQUIRED", stage);
73
+ const signer = current.list.keys.find((k) => equalBytes(k.keyId, parsed.authorityKeyId));
74
+ if (!signer)
75
+ throw new KavachError("RESET_KEY_REVOKED", stage, "the signing key is not in the current list");
76
+ const receipt = expectType(verifyDocument(receiptWire, signer.publicKey), DocumentType.AccountResetReceipt, stage);
77
+ const cert = expectType(verifyDocument(newCertificate), DocumentType.AccountDevice, stage);
78
+ const binding = { accountName: receipt.accountName, oldIdentityId: toHex(receipt.oldIdentityId), newIdentityId: toHex(receipt.newIdentityId) };
79
+ if (receipt.accountName !== accountName || cert.accountName !== accountName || !equalBytes(identityId(accountName, cert.accountKey), receipt.newIdentityId)) {
80
+ throw new KavachError("RESET_BINDING", stage, "receipt, account and certificate do not bind");
81
+ }
82
+ const resetId = toHex(receipt.resetId);
83
+ const known = this.state.events.get(resetId);
84
+ let outcome;
85
+ if (known) {
86
+ if (known.accountName !== binding.accountName || known.oldIdentityId !== binding.oldIdentityId || known.newIdentityId !== binding.newIdentityId) {
87
+ throw new KavachError("RESET_BINDING", stage, "a conflicting binding for a known reset id");
88
+ }
89
+ outcome = "DUPLICATE";
90
+ }
91
+ else {
92
+ if (!equalBytes(receipt.oldIdentityId, currentIdentityId) || this.state.retired.has(binding.newIdentityId)) {
93
+ throw new KavachError("RESET_BINDING", stage, "old identity is not the current pin, or the new one is retired");
94
+ }
95
+ outcome = "ACCOUNT_KEY_CHANGED";
96
+ }
97
+ const accepted = new Set(this.state.acceptedReceipts);
98
+ accepted.add(receiptHash);
99
+ const events = new Map(this.state.events);
100
+ events.set(resetId, binding);
101
+ const retired = new Set(this.state.retired);
102
+ retired.add(binding.oldIdentityId);
103
+ this.state = { ...this.state, acceptedReceipts: accepted, events, retired, timeHighWater: t };
104
+ return { outcome, oldIdentityId: receipt.oldIdentityId, newIdentityId: receipt.newIdentityId, receipt };
105
+ }
106
+ // Persistence ----------------------------------------------------------------------------------
107
+ toRows() {
108
+ return {
109
+ list: this.state.current ? { wire: toHex(this.state.current.wire), version: big(this.state.current.list.version), hash: toHex(this.state.current.list.bodyHash), checkedAt: big(this.state.timeHighWater) } : undefined,
110
+ clock: { highWater: big(this.state.timeHighWater) },
111
+ accepted: [...this.state.acceptedReceipts],
112
+ events: [...this.state.events.entries()].map(([resetId, b]) => ({ resetId, ...b })),
113
+ retired: [...this.state.retired]
114
+ };
115
+ }
116
+ static fromRows(config, rows) {
117
+ const current = rows.list ? { wire: fromHex(rows.list.wire), list: expectType(parseDocument(fromHex(rows.list.wire)), DocumentType.ResetKeyList) } : undefined;
118
+ return new ResetTrust(config, {
119
+ current,
120
+ timeHighWater: unbig(rows.clock.highWater),
121
+ acceptedReceipts: new Set(rows.accepted),
122
+ events: new Map(rows.events.map((e) => [e.resetId, { accountName: e.accountName, oldIdentityId: e.oldIdentityId, newIdentityId: e.newIdentityId }])),
123
+ retired: new Set(rows.retired)
124
+ });
125
+ }
126
+ }
127
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../src/reset.ts"],"names":[],"mappings":"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"}
package/dist/rows.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { CircleState } from "./circle.js";
2
+ import type { AccountPin } from "./identity.js";
3
+ import type { RevisionState } from "./audience.js";
4
+ import type { PreparedEpoch } from "./epoch.js";
5
+ import type { CircleRow, EpochRow, PinRow, RevisionRow } from "./store.js";
6
+ export declare const big: (v: bigint) => string;
7
+ export declare const unbig: (v: string) => bigint;
8
+ export declare function pinToRow(p: AccountPin): PinRow;
9
+ export declare function rowToPin(r: PinRow): AccountPin;
10
+ export declare function circleToRow(c: CircleState): CircleRow;
11
+ export declare function rowToCircle(r: CircleRow): CircleState;
12
+ export declare function revisionToRow(s: RevisionState, paused: RevisionRow["paused"]): RevisionRow;
13
+ export declare function rowToRevision(r: RevisionRow): RevisionState;
14
+ export declare function preparedToRow(p: PreparedEpoch): EpochRow;
15
+ export declare function rowToPrepared(r: EpochRow): PreparedEpoch;
16
+ //# sourceMappingURL=rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../src/rows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3E,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,KAAG,MAAsB,CAAC;AACvD,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,KAAG,MAAmB,CAAC;AAEtD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAc9C;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAc9C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,SAAS,CAYrD;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,WAAW,CAYrD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,WAAW,CAO1F;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,GAAG,aAAa,CAM3D;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,QAAQ,CAcxD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,QAAQ,GAAG,aAAa,CAWxD"}
package/dist/rows.js ADDED
@@ -0,0 +1,103 @@
1
+ /** Conversions between domain objects and the JSON-safe rows of the store. */
2
+ import { fromHex, toHex } from "./bytes.js";
3
+ export const big = (v) => v.toString();
4
+ export const unbig = (v) => BigInt(v);
5
+ export function pinToRow(p) {
6
+ return {
7
+ accountName: p.accountName,
8
+ accountKey: toHex(p.accountKey),
9
+ identityId: toHex(p.identityId),
10
+ generation: big(p.generation),
11
+ certificateHash: toHex(p.certificateHash),
12
+ certificate: toHex(p.certificate),
13
+ deviceId: toHex(p.deviceId),
14
+ signingKey: toHex(p.signingKey),
15
+ boxKey: toHex(p.boxKey),
16
+ streamId: toHex(p.streamId),
17
+ deviceIds: p.deviceIds.map(toHex)
18
+ };
19
+ }
20
+ export function rowToPin(r) {
21
+ return {
22
+ accountName: r.accountName,
23
+ accountKey: fromHex(r.accountKey),
24
+ identityId: fromHex(r.identityId),
25
+ generation: unbig(r.generation),
26
+ certificateHash: fromHex(r.certificateHash),
27
+ certificate: fromHex(r.certificate),
28
+ deviceId: fromHex(r.deviceId),
29
+ signingKey: fromHex(r.signingKey),
30
+ boxKey: fromHex(r.boxKey),
31
+ streamId: fromHex(r.streamId),
32
+ deviceIds: r.deviceIds.map(fromHex)
33
+ };
34
+ }
35
+ export function circleToRow(c) {
36
+ return {
37
+ circleId: toHex(c.circleId),
38
+ ownerIdentityId: toHex(c.ownerIdentityId),
39
+ revision: big(c.revision),
40
+ bodyHash: c.bodyHash ? toHex(c.bodyHash) : undefined,
41
+ snapshot: c.snapshot ? toHex(c.snapshot) : undefined,
42
+ members: c.members.map(toHex),
43
+ enabled: c.enabled,
44
+ status: c.status,
45
+ verifiedAt: big(c.verifiedAt)
46
+ };
47
+ }
48
+ export function rowToCircle(r) {
49
+ return {
50
+ circleId: fromHex(r.circleId),
51
+ ownerIdentityId: fromHex(r.ownerIdentityId),
52
+ revision: unbig(r.revision),
53
+ bodyHash: r.bodyHash ? fromHex(r.bodyHash) : undefined,
54
+ snapshot: r.snapshot ? fromHex(r.snapshot) : undefined,
55
+ members: r.members.map(fromHex),
56
+ enabled: r.enabled,
57
+ status: r.status,
58
+ verifiedAt: unbig(r.verifiedAt)
59
+ };
60
+ }
61
+ export function revisionToRow(s, paused) {
62
+ return {
63
+ desiredRevision: big(s.desiredRevision),
64
+ seenSnapshots: Object.fromEntries([...s.seenSnapshots].map(([k, v]) => [k, big(v)])),
65
+ seenCertificates: Object.fromEntries([...s.seenCertificates]),
66
+ paused
67
+ };
68
+ }
69
+ export function rowToRevision(r) {
70
+ return {
71
+ desiredRevision: unbig(r.desiredRevision),
72
+ seenSnapshots: new Map(Object.entries(r.seenSnapshots).map(([k, v]) => [k, unbig(v)])),
73
+ seenCertificates: new Map(Object.entries(r.seenCertificates))
74
+ };
75
+ }
76
+ export function preparedToRow(p) {
77
+ return {
78
+ epoch: p.epoch,
79
+ status: "prepared",
80
+ manifest: toHex(p.manifest),
81
+ manifestHash: toHex(p.manifestHash),
82
+ wraps: Object.fromEntries([...p.wraps].map(([k, v]) => [k, toHex(v)])),
83
+ epochKey: toHex(p.epochKey),
84
+ capturedRevision: big(p.capturedRevision),
85
+ audienceKey: p.audienceKey,
86
+ createdAt: big(p.createdAt),
87
+ nextCounter: 0,
88
+ lastSentAt: undefined
89
+ };
90
+ }
91
+ export function rowToPrepared(r) {
92
+ return {
93
+ epoch: r.epoch,
94
+ manifest: fromHex(r.manifest),
95
+ manifestHash: fromHex(r.manifestHash),
96
+ wraps: new Map(Object.entries(r.wraps).map(([k, v]) => [k, fromHex(v)])),
97
+ epochKey: fromHex(r.epochKey),
98
+ capturedRevision: unbig(r.capturedRevision),
99
+ audienceKey: r.audienceKey,
100
+ createdAt: unbig(r.createdAt)
101
+ };
102
+ }
103
+ //# sourceMappingURL=rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.js","sourceRoot":"","sources":["../src/rows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { NewestRow, Tx } from "./store.js";
2
+ export interface SlotOrder {
3
+ readonly generation: bigint;
4
+ readonly eventTime: bigint;
5
+ readonly epoch: number;
6
+ readonly counter: number;
7
+ }
8
+ export declare function compareSlotOrder(a: SlotOrder, b: SlotOrder): number;
9
+ /** The event time a slot orders by: the envelope's, never later than `sentAt`; `sentAt` when the sender gave none. */
10
+ export declare function clampEventTime(eventTime: bigint | undefined, sentAt: bigint): bigint;
11
+ export declare function slotKey(authorIdentityId: string, kind: number): string;
12
+ export declare function slotOrderOf(row: NewestRow): SlotOrder;
13
+ export interface SlotCandidate extends SlotOrder {
14
+ readonly recordId: string;
15
+ readonly bodyHash: string;
16
+ readonly sentAt: bigint;
17
+ readonly receivedAt: bigint;
18
+ readonly payload: Uint8Array;
19
+ }
20
+ /** Take the slot if the candidate orders after its current holder (or there is none); true when it did. */
21
+ export declare function takeSlot(tx: Tx, authorIdentityId: string, kind: number, c: SlotCandidate, toHex: (b: Uint8Array) => string): boolean;
22
+ //# sourceMappingURL=slots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../src/slots.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAInE;AAED,sHAAsH;AACtH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,wBAAgB,OAAO,CAAC,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAErD;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAED,2GAA2G;AAC3G,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,OAAO,CAOpI"}
package/dist/slots.js ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The newest slot (protocol section 10): for every kind declared `newest`, one row per author
3
+ * holding the newest record from the author's current device, shared by the receiver (T7) and
4
+ * the sender's own row (T6). Order: a newer device generation first; within one generation the
5
+ * later event time, clamped to the record's `sentAt` so a clock set ahead cannot hold the slot;
6
+ * equal event times by (epoch, counter). The slot outlives its payload: expiry drops the payload
7
+ * and keeps the order, so an older record replayed later cannot become current.
8
+ */
9
+ import { compareSlots } from "./record.js";
10
+ import { big, unbig } from "./rows.js";
11
+ export function compareSlotOrder(a, b) {
12
+ if (a.generation !== b.generation)
13
+ return a.generation < b.generation ? -1 : 1;
14
+ if (a.eventTime !== b.eventTime)
15
+ return a.eventTime < b.eventTime ? -1 : 1;
16
+ return compareSlots(a, b);
17
+ }
18
+ /** The event time a slot orders by: the envelope's, never later than `sentAt`; `sentAt` when the sender gave none. */
19
+ export function clampEventTime(eventTime, sentAt) {
20
+ return eventTime === undefined || eventTime > sentAt ? sentAt : eventTime;
21
+ }
22
+ export function slotKey(authorIdentityId, kind) {
23
+ return `${authorIdentityId}:${kind}`;
24
+ }
25
+ export function slotOrderOf(row) {
26
+ return { generation: unbig(row.generation), eventTime: unbig(row.eventTime), epoch: row.epoch, counter: row.counter };
27
+ }
28
+ /** Take the slot if the candidate orders after its current holder (or there is none); true when it did. */
29
+ export function takeSlot(tx, authorIdentityId, kind, c, toHex) {
30
+ const key = slotKey(authorIdentityId, kind);
31
+ const current = tx.get("newest", key);
32
+ if (current && compareSlotOrder(c, slotOrderOf(current)) <= 0)
33
+ return false;
34
+ const next = { recordId: c.recordId, bodyHash: c.bodyHash, generation: big(c.generation), epoch: c.epoch, counter: c.counter, sentAt: big(c.sentAt), receivedAt: big(c.receivedAt), eventTime: big(c.eventTime), payload: toHex(c.payload) };
35
+ tx.put("newest", key, next);
36
+ return true;
37
+ }
38
+ //# sourceMappingURL=slots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slots.js","sourceRoot":"","sources":["../src/slots.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAUvC,MAAM,UAAU,gBAAgB,CAAC,CAAY,EAAE,CAAY;IACzD,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU;QAAE,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS;QAAE,OAAO,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,OAAO,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,cAAc,CAAC,SAA6B,EAAE,MAAc;IAC1E,OAAO,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,gBAAwB,EAAE,IAAY;IAC5D,OAAO,GAAG,gBAAgB,IAAI,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAc;IACxC,OAAO,EAAE,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;AACxH,CAAC;AAUD,2GAA2G;AAC3G,MAAM,UAAU,QAAQ,CAAC,EAAM,EAAE,gBAAwB,EAAE,IAAY,EAAE,CAAgB,EAAE,KAAgC;IACzH,MAAM,GAAG,GAAG,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACtC,IAAI,OAAO,IAAI,gBAAgB,CAAC,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5E,MAAM,IAAI,GAAc,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACxP,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC;AACd,CAAC"}