agent-comms 8.6.1 → 8.7.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 (183) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +27 -1
  4. package/dist/account-cli.d.ts +34 -0
  5. package/dist/account-cli.d.ts.map +1 -0
  6. package/dist/account-cli.js +140 -0
  7. package/dist/account-cli.js.map +1 -0
  8. package/dist/account-join-cli.d.ts +17 -0
  9. package/dist/account-join-cli.d.ts.map +1 -0
  10. package/dist/account-join-cli.js +140 -0
  11. package/dist/account-join-cli.js.map +1 -0
  12. package/dist/bridges/mcp/server.d.ts +1 -4
  13. package/dist/bridges/mcp/server.d.ts.map +1 -1
  14. package/dist/bridges/mcp/server.js +1 -1
  15. package/dist/bridges/mcp/server.js.map +1 -1
  16. package/dist/cli.d.ts +4 -0
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/cli.js +24 -1
  19. package/dist/cli.js.map +1 -1
  20. package/dist/core/account-bundle.d.ts +22 -0
  21. package/dist/core/account-bundle.d.ts.map +1 -0
  22. package/dist/core/account-bundle.js +143 -0
  23. package/dist/core/account-bundle.js.map +1 -0
  24. package/dist/core/account-join.d.ts +62 -0
  25. package/dist/core/account-join.d.ts.map +1 -0
  26. package/dist/core/account-join.js +150 -0
  27. package/dist/core/account-join.js.map +1 -0
  28. package/dist/core/account-ledger-crypto.d.ts +28 -0
  29. package/dist/core/account-ledger-crypto.d.ts.map +1 -0
  30. package/dist/core/account-ledger-crypto.js +101 -0
  31. package/dist/core/account-ledger-crypto.js.map +1 -0
  32. package/dist/core/account-ledger-store.d.ts +21 -0
  33. package/dist/core/account-ledger-store.d.ts.map +1 -0
  34. package/dist/core/account-ledger-store.js +34 -0
  35. package/dist/core/account-ledger-store.js.map +1 -0
  36. package/dist/core/account-ledger.d.ts +80 -0
  37. package/dist/core/account-ledger.d.ts.map +1 -0
  38. package/dist/core/account-ledger.js +247 -0
  39. package/dist/core/account-ledger.js.map +1 -0
  40. package/dist/core/bridge-mesh.d.ts.map +1 -1
  41. package/dist/core/bridge-mesh.js +12 -1
  42. package/dist/core/bridge-mesh.js.map +1 -1
  43. package/dist/core/data-frame-routing.d.ts +50 -3
  44. package/dist/core/data-frame-routing.d.ts.map +1 -1
  45. package/dist/core/data-frame-routing.js +112 -5
  46. package/dist/core/data-frame-routing.js.map +1 -1
  47. package/dist/core/device-membership.d.ts +8 -8
  48. package/dist/core/device-membership.d.ts.map +1 -1
  49. package/dist/core/device-membership.js +17 -16
  50. package/dist/core/device-membership.js.map +1 -1
  51. package/dist/core/dm-send-delegation.d.ts +4 -4
  52. package/dist/core/dm-send-delegation.d.ts.map +1 -1
  53. package/dist/core/dm-send-delegation.js +2 -3
  54. package/dist/core/dm-send-delegation.js.map +1 -1
  55. package/dist/core/group-proofs.d.ts +5 -0
  56. package/dist/core/group-proofs.d.ts.map +1 -1
  57. package/dist/core/group-proofs.js +4 -0
  58. package/dist/core/group-proofs.js.map +1 -1
  59. package/dist/core/identity-store.d.ts.map +1 -1
  60. package/dist/core/identity-store.js +2 -62
  61. package/dist/core/identity-store.js.map +1 -1
  62. package/dist/core/issuer-identity-file.d.ts +4 -0
  63. package/dist/core/issuer-identity-file.d.ts.map +1 -1
  64. package/dist/core/issuer-identity-file.js +7 -5
  65. package/dist/core/issuer-identity-file.js.map +1 -1
  66. package/dist/core/ledger-lock.d.ts +12 -0
  67. package/dist/core/ledger-lock.d.ts.map +1 -0
  68. package/dist/core/ledger-lock.js +62 -0
  69. package/dist/core/ledger-lock.js.map +1 -0
  70. package/dist/core/membership-proofs.d.ts +7 -0
  71. package/dist/core/membership-proofs.d.ts.map +1 -1
  72. package/dist/core/membership-proofs.js +26 -1
  73. package/dist/core/membership-proofs.js.map +1 -1
  74. package/dist/core/mesh-store-shared.d.ts +4 -1
  75. package/dist/core/mesh-store-shared.d.ts.map +1 -1
  76. package/dist/core/mesh-store-shared.js.map +1 -1
  77. package/dist/core/mesh-store.d.ts +17 -8
  78. package/dist/core/mesh-store.d.ts.map +1 -1
  79. package/dist/core/mesh-store.js +41 -41
  80. package/dist/core/mesh-store.js.map +1 -1
  81. package/dist/core/peer-versions.d.ts +11 -0
  82. package/dist/core/peer-versions.d.ts.map +1 -1
  83. package/dist/core/peer-versions.js +9 -0
  84. package/dist/core/peer-versions.js.map +1 -1
  85. package/dist/core/pid-lock-file.d.ts +20 -0
  86. package/dist/core/pid-lock-file.d.ts.map +1 -0
  87. package/dist/core/pid-lock-file.js +115 -0
  88. package/dist/core/pid-lock-file.js.map +1 -0
  89. package/dist/core/room-lifecycle.d.ts +2 -2
  90. package/dist/core/room-lifecycle.d.ts.map +1 -1
  91. package/dist/core/room-lifecycle.js +18 -19
  92. package/dist/core/room-lifecycle.js.map +1 -1
  93. package/dist/core/transport-queries.d.ts +11 -0
  94. package/dist/core/transport-queries.d.ts.map +1 -0
  95. package/dist/core/transport-queries.js +30 -0
  96. package/dist/core/transport-queries.js.map +1 -0
  97. package/dist/core/user-identity.d.ts +23 -18
  98. package/dist/core/user-identity.d.ts.map +1 -1
  99. package/dist/core/user-identity.js +99 -61
  100. package/dist/core/user-identity.js.map +1 -1
  101. package/dist/core/wire-mesh-transport-options.d.ts +11 -2
  102. package/dist/core/wire-mesh-transport-options.d.ts.map +1 -1
  103. package/dist/core/wire-mesh-transport-options.js.map +1 -1
  104. package/dist/core/wire-mesh-transport.d.ts +4 -6
  105. package/dist/core/wire-mesh-transport.d.ts.map +1 -1
  106. package/dist/core/wire-mesh-transport.js +16 -20
  107. package/dist/core/wire-mesh-transport.js.map +1 -1
  108. package/dist/test/account-join.integration.test.d.ts +5 -0
  109. package/dist/test/account-join.integration.test.d.ts.map +1 -0
  110. package/dist/test/account-join.integration.test.js +183 -0
  111. package/dist/test/account-join.integration.test.js.map +1 -0
  112. package/dist/test/account-ledger-lock-worker.d.ts +9 -0
  113. package/dist/test/account-ledger-lock-worker.d.ts.map +1 -0
  114. package/dist/test/account-ledger-lock-worker.js +34 -0
  115. package/dist/test/account-ledger-lock-worker.js.map +1 -0
  116. package/dist/test/account-ledger-lock.integration.test.d.ts +5 -0
  117. package/dist/test/account-ledger-lock.integration.test.d.ts.map +1 -0
  118. package/dist/test/account-ledger-lock.integration.test.js +71 -0
  119. package/dist/test/account-ledger-lock.integration.test.js.map +1 -0
  120. package/dist/test/account-ledger-replication.integration.test.d.ts +5 -0
  121. package/dist/test/account-ledger-replication.integration.test.d.ts.map +1 -0
  122. package/dist/test/account-ledger-replication.integration.test.js +145 -0
  123. package/dist/test/account-ledger-replication.integration.test.js.map +1 -0
  124. package/dist/test/account-ledger.unit.test.d.ts +5 -0
  125. package/dist/test/account-ledger.unit.test.d.ts.map +1 -0
  126. package/dist/test/account-ledger.unit.test.js +317 -0
  127. package/dist/test/account-ledger.unit.test.js.map +1 -0
  128. package/dist/test/account-transfer.unit.test.d.ts +5 -0
  129. package/dist/test/account-transfer.unit.test.d.ts.map +1 -0
  130. package/dist/test/account-transfer.unit.test.js +204 -0
  131. package/dist/test/account-transfer.unit.test.js.map +1 -0
  132. package/dist/test/delivery-engine-delivery.unit.test.js +1 -0
  133. package/dist/test/delivery-engine-delivery.unit.test.js.map +1 -1
  134. package/dist/test/delivery-engine-directed-notify.unit.test.js +1 -0
  135. package/dist/test/delivery-engine-directed-notify.unit.test.js.map +1 -1
  136. package/dist/test/delivery-engine-own-agent.unit.test.js +1 -0
  137. package/dist/test/delivery-engine-own-agent.unit.test.js.map +1 -1
  138. package/dist/test/delivery-engine.unit.test.js +1 -0
  139. package/dist/test/delivery-engine.unit.test.js.map +1 -1
  140. package/dist/test/device-membership.unit.test.js +81 -30
  141. package/dist/test/device-membership.unit.test.js.map +1 -1
  142. package/dist/test/dm-send-delegation.unit.test.js +25 -14
  143. package/dist/test/dm-send-delegation.unit.test.js.map +1 -1
  144. package/dist/test/dm-send-principal-delegation.integration.test.js +9 -2
  145. package/dist/test/dm-send-principal-delegation.integration.test.js.map +1 -1
  146. package/dist/test/hidden-line.unit.test.d.ts +5 -0
  147. package/dist/test/hidden-line.unit.test.d.ts.map +1 -0
  148. package/dist/test/hidden-line.unit.test.js +40 -0
  149. package/dist/test/hidden-line.unit.test.js.map +1 -0
  150. package/dist/test/identity-restart.integration.test.js +8 -1
  151. package/dist/test/identity-restart.integration.test.js.map +1 -1
  152. package/dist/test/mcp-stdout-channel.integration.test.js +2 -2
  153. package/dist/test/mcp-stdout-channel.integration.test.js.map +1 -1
  154. package/dist/test/mesh-smoke.runner.js +2 -1
  155. package/dist/test/mesh-smoke.runner.js.map +1 -1
  156. package/dist/test/room-join-admission.integration.test.js +8 -1
  157. package/dist/test/room-join-admission.integration.test.js.map +1 -1
  158. package/dist/test/room-lifecycle-bare-name.unit.test.js +1 -0
  159. package/dist/test/room-lifecycle-bare-name.unit.test.js.map +1 -1
  160. package/dist/test/room-lifecycle-membership.unit.test.js +1 -0
  161. package/dist/test/room-lifecycle-membership.unit.test.js.map +1 -1
  162. package/dist/test/room-lifecycle-remote.unit.test.js +1 -0
  163. package/dist/test/room-lifecycle-remote.unit.test.js.map +1 -1
  164. package/dist/test/room-lifecycle.unit.test.js +1 -0
  165. package/dist/test/room-lifecycle.unit.test.js.map +1 -1
  166. package/dist/test/room-messaging-durable-send.unit.test.js +1 -0
  167. package/dist/test/room-messaging-durable-send.unit.test.js.map +1 -1
  168. package/dist/test/room-messaging.unit.test.js +1 -0
  169. package/dist/test/room-messaging.unit.test.js.map +1 -1
  170. package/dist/test/room-protocol-notify.unit.test.js +1 -0
  171. package/dist/test/room-protocol-notify.unit.test.js.map +1 -1
  172. package/dist/test/room-protocol.helper.d.ts.map +1 -1
  173. package/dist/test/room-protocol.helper.js +1 -0
  174. package/dist/test/room-protocol.helper.js.map +1 -1
  175. package/dist/test/room-send-retry.integration.test.js +8 -1
  176. package/dist/test/room-send-retry.integration.test.js.map +1 -1
  177. package/dist/test/test-transport.d.ts +9 -0
  178. package/dist/test/test-transport.d.ts.map +1 -1
  179. package/dist/test/test-transport.js +14 -5
  180. package/dist/test/test-transport.js.map +1 -1
  181. package/dist/test/user-identity.unit.test.js +75 -106
  182. package/dist/test/user-identity.unit.test.js.map +1 -1
  183. package/package.json +2 -2
@@ -0,0 +1,101 @@
1
+ /**
2
+ * The confidentiality layer of the account's replicated grant ledger (agent-comms#344). A `core/data` entry is opaque bytes to the transport and is replicated to whoever asks for it, so every ledger entry is sealed with a key only a holder of the account's private key can derive: AES-256-GCM under an HKDF-SHA256 key from the account key, with the log it belongs to and its sequence number bound in as associated data so a relayer can neither read an entry nor move one to another log or position. The same derivation gives each machine's writer log an id that any account holder recognises and nobody else can distinguish from a random device-id.
3
+ */
4
+ import { createCipheriv, createDecipheriv, createHmac, createPrivateKey, hkdfSync, randomBytes, timingSafeEqual, } from "node:crypto";
5
+ /** AES-256 takes a 256-bit key. */
6
+ const KEY_BYTES = 32;
7
+ /** The 96-bit IV GCM is specified for; any other length is hashed into one, which weakens its guarantees. */
8
+ const IV_BYTES = 12;
9
+ /** GCM's full-length authentication tag. */
10
+ const TAG_BYTES = 16;
11
+ /** The first byte of every sealed entry, so a later format can be told apart from this one. */
12
+ const SEALED_ENTRY_VERSION = 1;
13
+ const VERSION_BYTES = 1;
14
+ /** A data-domain log id is a device-id, which is a SHA-256 digest. */
15
+ export const WRITER_LOG_ID_BYTES = 32;
16
+ /** The random half of a writer log id; the other half authenticates it. */
17
+ export const WRITER_NONCE_BYTES = WRITER_LOG_ID_BYTES / 2;
18
+ /** A sequence number is bound into the associated data as a 64-bit big-endian integer. */
19
+ const SEQ_BYTES = 8;
20
+ const ENTRY_KEY_INFO = "agent-comms/account-ledger/entry/v1";
21
+ const WRITER_KEY_INFO = "agent-comms/account-ledger/writer/v1";
22
+ const ASSOCIATED_DATA_LABEL = "agent-comms/account-ledger/v1";
23
+ /** Derives the ledger's keys from the account's PEM private key. Every copy of the same account key derives the same keys, which is what lets every machine holding it read what any of them wrote. */
24
+ export function deriveAccountLedgerKeys(accountPrivateKeyPem) {
25
+ const ikm = createPrivateKey(accountPrivateKeyPem).export({
26
+ format: "der",
27
+ type: "pkcs8",
28
+ });
29
+ const derive = (info) => Buffer.from(hkdfSync("sha256", ikm, Buffer.alloc(0), info, KEY_BYTES));
30
+ return {
31
+ entryKey: derive(ENTRY_KEY_INFO),
32
+ writerKey: derive(WRITER_KEY_INFO),
33
+ };
34
+ }
35
+ function writerTag(writerKey, nonce) {
36
+ return createHmac("sha256", writerKey)
37
+ .update(nonce)
38
+ .digest()
39
+ .subarray(0, WRITER_LOG_ID_BYTES - WRITER_NONCE_BYTES);
40
+ }
41
+ /** A fresh random writer nonce, generated once per machine. */
42
+ export function generateWriterNonce() {
43
+ return Uint8Array.from(randomBytes(WRITER_NONCE_BYTES));
44
+ }
45
+ /** The log id a machine with this writer nonce appends the account's ledger entries under: the nonce followed by a truncated HMAC of it under the account's writer key. */
46
+ export function writerLogId(keys, nonce) {
47
+ if (nonce.length !== WRITER_NONCE_BYTES) {
48
+ throw new Error(`a writer nonce is ${String(WRITER_NONCE_BYTES)} bytes, got ${String(nonce.length)}`);
49
+ }
50
+ const id = new Uint8Array(WRITER_LOG_ID_BYTES);
51
+ id.set(nonce, 0);
52
+ id.set(writerTag(keys.writerKey, nonce), WRITER_NONCE_BYTES);
53
+ return id;
54
+ }
55
+ /** Whether a log id is one of this account's writer logs. Only a holder of the account key can tell; to anyone else it is indistinguishable from a device-id. */
56
+ export function isWriterLogId(keys, logId) {
57
+ if (logId.length !== WRITER_LOG_ID_BYTES)
58
+ return false;
59
+ const expected = writerTag(keys.writerKey, logId.subarray(0, WRITER_NONCE_BYTES));
60
+ return timingSafeEqual(expected, logId.subarray(WRITER_NONCE_BYTES));
61
+ }
62
+ function associatedData(logId, seq) {
63
+ const seqBytes = Buffer.alloc(SEQ_BYTES);
64
+ seqBytes.writeBigUInt64BE(BigInt(seq));
65
+ return Buffer.concat([Buffer.from(ASSOCIATED_DATA_LABEL), logId, seqBytes]);
66
+ }
67
+ /** Seals one ledger entry's plaintext for position `seq` of log `logId`: version, IV, tag, then ciphertext. */
68
+ export function sealLedgerEntry(keys, logId, seq, plaintext) {
69
+ const iv = randomBytes(IV_BYTES);
70
+ const cipher = createCipheriv("aes-256-gcm", keys.entryKey, iv);
71
+ cipher.setAAD(associatedData(logId, seq));
72
+ const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
73
+ return Uint8Array.from(Buffer.concat([
74
+ Buffer.from([SEALED_ENTRY_VERSION]),
75
+ iv,
76
+ cipher.getAuthTag(),
77
+ ciphertext,
78
+ ]));
79
+ }
80
+ /** Opens a sealed entry, or returns undefined if it was not sealed by a holder of this account key for exactly this log and position (tampered, moved, truncated, or someone else's). */
81
+ export function openLedgerEntry(keys, logId, seq, sealed) {
82
+ const headerBytes = VERSION_BYTES + IV_BYTES + TAG_BYTES;
83
+ if (sealed.length < headerBytes || sealed[0] !== SEALED_ENTRY_VERSION) {
84
+ return undefined;
85
+ }
86
+ const iv = sealed.subarray(VERSION_BYTES, VERSION_BYTES + IV_BYTES);
87
+ const tag = sealed.subarray(VERSION_BYTES + IV_BYTES, headerBytes);
88
+ const decipher = createDecipheriv("aes-256-gcm", keys.entryKey, iv);
89
+ decipher.setAAD(associatedData(logId, seq));
90
+ decipher.setAuthTag(tag);
91
+ try {
92
+ return Uint8Array.from(Buffer.concat([
93
+ decipher.update(sealed.subarray(headerBytes)),
94
+ decipher.final(),
95
+ ]));
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ }
101
+ //# sourceMappingURL=account-ledger-crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-ledger-crypto.js","sourceRoot":"","sources":["../../src/core/account-ledger-crypto.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Opens this machine's copy of the account's replicated grant ledger (account-ledger.ts): a filesystem store beside user-identity.json, shared by every bridge on the machine, and the one-time migration of a pre-ledger user-identity.json's own issued-grant maps into it.
3
+ */
4
+ import type { Clock } from "wire-mesh-core/ports/clock";
5
+ import { AccountLedger } from "./account-ledger.js";
6
+ import type { PeerIdentity } from "./identity.js";
7
+ import { type UserIdentityOptions } from "./user-identity.js";
8
+ export interface OpenAccountLedgerOptions {
9
+ /** Where user-identity.json lives; the ledger is kept beside it. */
10
+ userIdentityOptions: Readonly<UserIdentityOptions>;
11
+ /** The account's identity as loadOrCreateUserIdentity returned it. */
12
+ userIdentity: Readonly<PeerIdentity>;
13
+ clock: Clock;
14
+ }
15
+ /** The directory an account's ledger is stored in on this machine. Named by the account's device-id, so a machine that imports a different account starts that account's ledger afresh instead of mixing two accounts' logs. */
16
+ export declare function accountLedgerDir(userIdentityOptions: Readonly<UserIdentityOptions>, userIdentity: Readonly<PeerIdentity>): string;
17
+ /**
18
+ * Opens the account ledger for this machine and migrates any grants a pre-ledger build recorded in user-identity.json into it, so an existing user-identity.json needs no manual step: every grant it knew about stays revocable, now from any machine holding the key. The legacy maps are removed only after their grants are in the ledger, so a crash between the two re-migrates them on the next start, which is harmless because the ledger folds a grant recorded twice into one.
19
+ */
20
+ export declare function openAccountLedger(options: Readonly<OpenAccountLedgerOptions>): Promise<AccountLedger>;
21
+ //# sourceMappingURL=account-ledger-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-ledger-store.d.ts","sourceRoot":"","sources":["../../src/core/account-ledger-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAKL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACnD,sEAAsE;IACtE,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACrC,KAAK,EAAE,KAAK,CAAC;CACd;AAED,gOAAgO;AAChO,wBAAgB,gBAAgB,CAC9B,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAClD,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,GACnC,MAAM,CAKR;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,QAAQ,CAAC,wBAAwB,CAAC,GAC1C,OAAO,CAAC,aAAa,CAAC,CAqBxB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Opens this machine's copy of the account's replicated grant ledger (account-ledger.ts): a filesystem store beside user-identity.json, shared by every bridge on the machine, and the one-time migration of a pre-ledger user-identity.json's own issued-grant maps into it.
3
+ */
4
+ import * as path from "node:path";
5
+ import { createNodeFsStorage } from "wire-mesh-core/adapters/node-fs-storage";
6
+ import { deviceIdToHex } from "wire-mesh-core/domain/device-id";
7
+ import { generateWriterNonce } from "./account-ledger-crypto.js";
8
+ import { AccountLedger } from "./account-ledger.js";
9
+ import { createFileLedgerLock } from "./ledger-lock.js";
10
+ import { clearLegacyIssuedGrants, loadOrCreateLedgerWriterNonce, readLegacyIssuedGrants, userIdentityDir, } from "./user-identity.js";
11
+ /** The directory an account's ledger is stored in on this machine. Named by the account's device-id, so a machine that imports a different account starts that account's ledger afresh instead of mixing two accounts' logs. */
12
+ export function accountLedgerDir(userIdentityOptions, userIdentity) {
13
+ return path.join(userIdentityDir(userIdentityOptions), `account-ledger-${deviceIdToHex(Uint8Array.from(userIdentity.deviceId))}`);
14
+ }
15
+ /**
16
+ * Opens the account ledger for this machine and migrates any grants a pre-ledger build recorded in user-identity.json into it, so an existing user-identity.json needs no manual step: every grant it knew about stays revocable, now from any machine holding the key. The legacy maps are removed only after their grants are in the ledger, so a crash between the two re-migrates them on the next start, which is harmless because the ledger folds a grant recorded twice into one.
17
+ */
18
+ export async function openAccountLedger(options) {
19
+ const dir = accountLedgerDir(options.userIdentityOptions, options.userIdentity);
20
+ const ledger = new AccountLedger({
21
+ accountPrivateKey: options.userIdentity.privateKey,
22
+ writerNonce: loadOrCreateLedgerWriterNonce(options.userIdentityOptions, generateWriterNonce),
23
+ storage: createNodeFsStorage({ dir }),
24
+ lock: createFileLedgerLock(`${dir}.lock`),
25
+ clock: options.clock,
26
+ });
27
+ const legacy = readLegacyIssuedGrants(options.userIdentityOptions);
28
+ if (legacy.length > 0) {
29
+ await ledger.recordGrants(legacy);
30
+ clearLegacyIssuedGrants(options.userIdentityOptions, legacy);
31
+ }
32
+ return ledger;
33
+ }
34
+ //# sourceMappingURL=account-ledger-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-ledger-store.js","sourceRoot":"","sources":["../../src/core/account-ledger-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,sBAAsB,EACtB,eAAe,GAEhB,MAAM,oBAAoB,CAAC;AAU5B,gOAAgO;AAChO,MAAM,UAAU,gBAAgB,CAC9B,mBAAkD,EAClD,YAAoC;IAEpC,OAAO,IAAI,CAAC,IAAI,CACd,eAAe,CAAC,mBAAmB,CAAC,EACpC,kBAAkB,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,CAC1E,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAA2C;IAE3C,MAAM,GAAG,GAAG,gBAAgB,CAC1B,OAAO,CAAC,mBAAmB,EAC3B,OAAO,CAAC,YAAY,CACrB,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC;QAC/B,iBAAiB,EAAE,OAAO,CAAC,YAAY,CAAC,UAAU;QAClD,WAAW,EAAE,6BAA6B,CACxC,OAAO,CAAC,mBAAmB,EAC3B,mBAAmB,CACpB;QACD,OAAO,EAAE,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC;QACrC,IAAI,EAAE,oBAAoB,CAAC,GAAG,GAAG,OAAO,CAAC;QACzC,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,uBAAuB,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The account's issued-grant ledger as a replicated object (agent-comms#344), following wire-mesh's replicated issuer grant ledger pattern (spec/PATTERNS.md). A token-id never appears on the wire except inside the grant it names, so the only record that a grant exists is what its issuer kept; with the ledger in one machine's user-identity.json, only that machine could revoke what it minted. Here every grant the account's user principal mints, and every revocation of one, is an entry in a `core/data` log, and the logs replicate by data-domain fan-out to every machine holding the account key, so any of them sees every admission and can revoke it.
3
+ *
4
+ * Each machine appends to a writer log of its own rather than all of them sharing one: a data-domain log is single-writer, and two machines appending to one log while apart would both write the same sequence number and fork it, silently losing one side's grants. A writer log's id is self-authenticating (account-ledger-crypto.ts), so any account holder recognises every writer log it is offered without a roster, and the ledger is the union of all of them.
5
+ *
6
+ * Holding a replica grants no authority: an entry is sealed under a key derived from the account key, so a replica held by anyone else is ciphertext they can neither read nor forge, and minting or revoking still needs the account's private key.
7
+ */
8
+ import { type DataEntriesFrame, type DataHaveFrame, type DataRequestFrame, type DeviceId, type RevocationEntry } from "wire-mesh-core/generated/protocol";
9
+ import type { RevocationView } from "wire-mesh-core/domain/revocation-view";
10
+ import type { Clock } from "wire-mesh-core/ports/clock";
11
+ import type { IdentityPort } from "wire-mesh-core/ports/identity";
12
+ import type { KeyValueStorage } from "wire-mesh-core/ports/storage";
13
+ import type { LedgerLock } from "./ledger-lock.js";
14
+ /** Which of the principal's grant kinds an entry is about: a device's own group:member admission (device-membership.ts), or a dm:send grant (room-lifecycle.ts, dm-send-delegation.ts). Each kind is keyed by the grant's bearer, so the two never share a namespace. */
15
+ export type IssuedGrantKind = "device" | "dm";
16
+ /** One grant the ledger records as issued and not revoked. */
17
+ export interface OutstandingGrant {
18
+ tokenId: Uint8Array<ArrayBuffer>;
19
+ /** When it was recorded (epoch ms, the recording machine's clock). */
20
+ at: number;
21
+ }
22
+ export interface AccountLedgerDeps {
23
+ /** The account's PEM private key: every ledger key is derived from it. */
24
+ accountPrivateKey: string;
25
+ /** This machine's writer nonce, persisted once per machine (user-identity.ts). */
26
+ writerNonce: Uint8Array;
27
+ /** Holds every account writer log this machine has, its own included. Shared by every bridge on the machine. */
28
+ storage: KeyValueStorage;
29
+ /** Serialises every read and write of `storage` across every bridge sharing it: appends to this machine's writer log, replicated entries stored for another machine's, and every read of either. The store's writes are not atomic (a file is truncated, then written), so a read racing another bridge's write could see an empty head and treat a log as empty. */
30
+ lock: LedgerLock;
31
+ clock: Clock;
32
+ }
33
+ /** Answers and stores the data-domain frames for the account's writer logs; what a transport needs of the ledger to replicate it. */
34
+ export interface AccountLedgerReplica {
35
+ /** Whether `peer` names one of this account's writer logs. */
36
+ ownsLog: (peer: DeviceId) => boolean;
37
+ /** Answers a have or request for an account log, or stores entries for one after checking every entry was sealed for exactly that log and position. Returns the frame to send back, or null for none. */
38
+ handleDataFrame: (frame: Readonly<DataHaveFrame | DataRequestFrame | DataEntriesFrame>) => Promise<DataHaveFrame | DataRequestFrame | DataEntriesFrame | null>;
39
+ /** A data-have for every account log this machine holds, to offer peers. */
40
+ announcements: () => Promise<DataHaveFrame[]>;
41
+ }
42
+ export declare class AccountLedger implements AccountLedgerReplica {
43
+ private readonly deps;
44
+ /** This machine's own writer log. */
45
+ readonly writerLog: DeviceId;
46
+ private readonly keys;
47
+ private readonly revocationListeners;
48
+ constructor(deps: Readonly<AccountLedgerDeps>);
49
+ /** Records that the principal minted `tokenId` for `subjectHex`. */
50
+ recordGrant(kind: IssuedGrantKind, subjectHex: string, tokenId: Uint8Array<ArrayBuffer>): Promise<void>;
51
+ /** Records grants migrated from a pre-ledger user-identity.json in one append, so a restart part-way through leaves nothing half-recorded worth caring about: a grant recorded twice folds to one. */
52
+ recordGrants(grants: readonly Readonly<{
53
+ kind: IssuedGrantKind;
54
+ subject: string;
55
+ tokenId: Uint8Array<ArrayBuffer>;
56
+ }>[]): Promise<void>;
57
+ /** Records the revocation of `tokenId`, carrying the signed revocation entry itself so every replica can feed it into its own RevocationView. */
58
+ recordRevocation(kind: IssuedGrantKind, subjectHex: string, tokenId: Uint8Array<ArrayBuffer>, revocation: RevocationEntry): Promise<void>;
59
+ /** Every grant of `kind` for `subjectHex` that some machine of the account recorded and none has revoked, oldest first. */
60
+ outstandingGrants(kind: IssuedGrantKind, subjectHex: string): Promise<OutstandingGrant[]>;
61
+ /** Every revocation entry the ledger holds, from every machine, for a RevocationView to learn at start-up. */
62
+ revocations(): Promise<RevocationEntry[]>;
63
+ ownsLog(peer: DeviceId): boolean;
64
+ /** Calls `listener` with each revocation entry another machine's replicated log brings in, so a RevocationView learns it even if the gossiped revocation-announce never reached this node. Returns the unsubscribe. */
65
+ onReplicatedRevocation(listener: (entry: RevocationEntry) => void): () => void;
66
+ announcements(): Promise<DataHaveFrame[]>;
67
+ handleDataFrame(frame: Readonly<DataHaveFrame | DataRequestFrame | DataEntriesFrame>): Promise<DataHaveFrame | DataRequestFrame | DataEntriesFrame | null>;
68
+ private append;
69
+ /** Every account writer log in storage, this machine's own included once it has written anything. Called only under the lock. */
70
+ private heldLogs;
71
+ /** Every record in every held writer log. Throws on an entry that does not open: handleDataFrame and append never store one, so it means the storage was damaged outside the ledger, and carrying on would hide grants that can then never be revoked. */
72
+ private records;
73
+ }
74
+ /** Feeds every revocation the account ledger holds, and each one another machine's log brings in later, into a store's RevocationView, so a grant any machine of the account revoked is refused there even if the gossiped revocation-announce never reached it. A revocation that fails to verify, or a ledger that cannot be read, is reported rather than recorded. Returns the unsubscribe, for a store that replaces its ledger on joining another account. */
75
+ export declare function followLedgerRevocations(identity: Readonly<{
76
+ accountLedger: AccountLedger;
77
+ revocation: RevocationView;
78
+ identity: IdentityPort;
79
+ }>, onError: (error: Error) => void): () => void;
80
+ //# sourceMappingURL=account-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-ledger.d.ts","sourceRoot":"","sources":["../../src/core/account-ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,247 @@
1
+ /**
2
+ * The account's issued-grant ledger as a replicated object (agent-comms#344), following wire-mesh's replicated issuer grant ledger pattern (spec/PATTERNS.md). A token-id never appears on the wire except inside the grant it names, so the only record that a grant exists is what its issuer kept; with the ledger in one machine's user-identity.json, only that machine could revoke what it minted. Here every grant the account's user principal mints, and every revocation of one, is an entry in a `core/data` log, and the logs replicate by data-domain fan-out to every machine holding the account key, so any of them sees every admission and can revoke it.
3
+ *
4
+ * Each machine appends to a writer log of its own rather than all of them sharing one: a data-domain log is single-writer, and two machines appending to one log while apart would both write the same sequence number and fork it, silently losing one side's grants. A writer log's id is self-authenticating (account-ledger-crypto.ts), so any account holder recognises every writer log it is offered without a roster, and the ledger is the union of all of them.
5
+ *
6
+ * Holding a replica grants no authority: an entry is sealed under a key derived from the account key, so a replica held by anyone else is ciphertext they can neither read nor forge, and minting or revoking still needs the account's private key.
7
+ */
8
+ import { decode as cborDecode, encode as cborEncode, cdeEncodeOptions, } from "cbor2";
9
+ import { z } from "zod";
10
+ import { handleDataEntries, handleDataHave, handleDataRequest, headSeqFor, readEntries, } from "wire-mesh-core/domain/data-sync";
11
+ import { deviceIdFromHex, deviceIdToHex, } from "wire-mesh-core/domain/device-id";
12
+ import { revocationEntrySchema, } from "wire-mesh-core/generated/protocol";
13
+ import { deriveAccountLedgerKeys, isWriterLogId, openLedgerEntry, sealLedgerEntry, writerLogId, } from "./account-ledger-crypto.js";
14
+ import { DATA_ENTRIES_RESPONSE_LIMIT } from "./data-frame-routing.js";
15
+ const LEDGER_RECORD_VERSION = 1;
16
+ const bytesSchema = z.instanceof(Uint8Array);
17
+ const kindSchema = z.enum(["device", "dm"]);
18
+ const grantRecordSchema = z
19
+ .object({
20
+ v: z.literal(LEDGER_RECORD_VERSION),
21
+ op: z.literal("grant"),
22
+ kind: kindSchema,
23
+ subject: z.string(),
24
+ tokenId: bytesSchema,
25
+ at: z.number(),
26
+ })
27
+ .strict();
28
+ const revokeRecordSchema = z
29
+ .object({
30
+ v: z.literal(LEDGER_RECORD_VERSION),
31
+ op: z.literal("revoke"),
32
+ kind: kindSchema,
33
+ subject: z.string(),
34
+ tokenId: bytesSchema,
35
+ at: z.number(),
36
+ revocation: revocationEntrySchema,
37
+ })
38
+ .strict();
39
+ const ledgerRecordSchema = z.discriminatedUnion("op", [
40
+ grantRecordSchema,
41
+ revokeRecordSchema,
42
+ ]);
43
+ const versionProbeSchema = z.object({ v: z.number() });
44
+ const HEAD_KEY_PATTERN = /^data\/([0-9a-f]+)\/head$/;
45
+ export class AccountLedger {
46
+ deps;
47
+ /** This machine's own writer log. */
48
+ writerLog;
49
+ keys;
50
+ revocationListeners = new Set();
51
+ constructor(deps) {
52
+ this.deps = deps;
53
+ this.keys = deriveAccountLedgerKeys(deps.accountPrivateKey);
54
+ this.writerLog = writerLogId(this.keys, deps.writerNonce);
55
+ }
56
+ /** Records that the principal minted `tokenId` for `subjectHex`. */
57
+ async recordGrant(kind, subjectHex, tokenId) {
58
+ await this.append([
59
+ {
60
+ v: LEDGER_RECORD_VERSION,
61
+ op: "grant",
62
+ kind,
63
+ subject: subjectHex,
64
+ tokenId,
65
+ at: this.deps.clock.now(),
66
+ },
67
+ ]);
68
+ }
69
+ /** Records grants migrated from a pre-ledger user-identity.json in one append, so a restart part-way through leaves nothing half-recorded worth caring about: a grant recorded twice folds to one. */
70
+ async recordGrants(grants) {
71
+ const at = this.deps.clock.now();
72
+ await this.append(grants.map((grant) => ({
73
+ v: LEDGER_RECORD_VERSION,
74
+ op: "grant",
75
+ kind: grant.kind,
76
+ subject: grant.subject,
77
+ tokenId: grant.tokenId,
78
+ at,
79
+ })));
80
+ }
81
+ /** Records the revocation of `tokenId`, carrying the signed revocation entry itself so every replica can feed it into its own RevocationView. */
82
+ async recordRevocation(kind, subjectHex, tokenId, revocation) {
83
+ await this.append([
84
+ {
85
+ v: LEDGER_RECORD_VERSION,
86
+ op: "revoke",
87
+ kind,
88
+ subject: subjectHex,
89
+ tokenId,
90
+ at: this.deps.clock.now(),
91
+ revocation,
92
+ },
93
+ ]);
94
+ }
95
+ /** Every grant of `kind` for `subjectHex` that some machine of the account recorded and none has revoked, oldest first. */
96
+ async outstandingGrants(kind, subjectHex) {
97
+ const granted = new Map();
98
+ const revoked = new Set();
99
+ for (const record of await this.records()) {
100
+ if (record.kind !== kind || record.subject !== subjectHex)
101
+ continue;
102
+ const key = Buffer.from(record.tokenId).toString("hex");
103
+ if (record.op === "revoke") {
104
+ revoked.add(key);
105
+ }
106
+ else if (!granted.has(key)) {
107
+ granted.set(key, {
108
+ tokenId: Uint8Array.from(record.tokenId),
109
+ at: record.at,
110
+ });
111
+ }
112
+ }
113
+ return [...granted]
114
+ .filter(([key]) => !revoked.has(key))
115
+ .map(([, grant]) => grant)
116
+ .sort((a, b) => a.at - b.at);
117
+ }
118
+ /** Every revocation entry the ledger holds, from every machine, for a RevocationView to learn at start-up. */
119
+ async revocations() {
120
+ return (await this.records()).flatMap((record) => record.op === "revoke" ? [record.revocation] : []);
121
+ }
122
+ ownsLog(peer) {
123
+ return isWriterLogId(this.keys, peer);
124
+ }
125
+ /** Calls `listener` with each revocation entry another machine's replicated log brings in, so a RevocationView learns it even if the gossiped revocation-announce never reached this node. Returns the unsubscribe. */
126
+ onReplicatedRevocation(listener) {
127
+ this.revocationListeners.add(listener);
128
+ return () => {
129
+ this.revocationListeners.delete(listener);
130
+ };
131
+ }
132
+ async announcements() {
133
+ return this.deps.lock.run(async () => {
134
+ const frames = [];
135
+ for (const log of await this.heldLogs()) {
136
+ frames.push({
137
+ type: "data-have",
138
+ peer: log,
139
+ "head-seq": await headSeqFor(this.deps.storage, log),
140
+ });
141
+ }
142
+ return frames;
143
+ });
144
+ }
145
+ async handleDataFrame(frame) {
146
+ const { storage, lock } = this.deps;
147
+ if (frame.type === "data-have") {
148
+ return lock.run(async () => handleDataHave(storage, frame));
149
+ }
150
+ if (frame.type === "data-request") {
151
+ return lock.run(async () => handleDataRequest(storage, frame, DATA_ENTRIES_RESPONSE_LIMIT));
152
+ }
153
+ // Every entry must open for exactly its log and position before any is stored: a forged or moved entry would otherwise take a sequence number the real one can then never fill.
154
+ const firstSeq = frame["from-seq"] + 1;
155
+ const opened = frame.entries.map((entry, index) => openLedgerEntry(this.keys, frame.peer, firstSeq + index, entry));
156
+ const plaintexts = opened.filter((plaintext) => plaintext !== undefined);
157
+ if (plaintexts.length !== opened.length)
158
+ return null;
159
+ const stored = await lock.run(async () => handleDataEntries(storage, frame));
160
+ if (!stored.ok)
161
+ return null;
162
+ for (const plaintext of plaintexts) {
163
+ const record = decodeRecord(plaintext);
164
+ if (record?.op !== "revoke")
165
+ continue;
166
+ for (const listener of this.revocationListeners) {
167
+ listener(record.revocation);
168
+ }
169
+ }
170
+ return null;
171
+ }
172
+ async append(records) {
173
+ await this.deps.lock.run(async () => {
174
+ const head = await headSeqFor(this.deps.storage, this.writerLog);
175
+ const entries = records.map((record, index) => sealLedgerEntry(this.keys, this.writerLog, head + 1 + index, Uint8Array.from(cborEncode(record, cdeEncodeOptions))));
176
+ await handleDataEntries(this.deps.storage, {
177
+ type: "data-entries",
178
+ peer: this.writerLog,
179
+ "from-seq": head,
180
+ entries,
181
+ });
182
+ });
183
+ }
184
+ /** Every account writer log in storage, this machine's own included once it has written anything. Called only under the lock. */
185
+ async heldLogs() {
186
+ const logs = [];
187
+ for (const key of await this.deps.storage.keys("data/")) {
188
+ const match = HEAD_KEY_PATTERN.exec(key);
189
+ if (match?.[1] === undefined)
190
+ continue;
191
+ const log = deviceIdFromHex(match[1]);
192
+ if (this.ownsLog(log))
193
+ logs.push(log);
194
+ }
195
+ return logs;
196
+ }
197
+ /** Every record in every held writer log. Throws on an entry that does not open: handleDataFrame and append never store one, so it means the storage was damaged outside the ledger, and carrying on would hide grants that can then never be revoked. */
198
+ async records() {
199
+ const held = await this.deps.lock.run(async () => Promise.all((await this.heldLogs()).map(async (log) => ({
200
+ log,
201
+ entries: await readEntries(this.deps.storage, log, 0),
202
+ }))));
203
+ const records = [];
204
+ for (const { log, entries } of held) {
205
+ entries.forEach((sealed, index) => {
206
+ const seq = index + 1;
207
+ const plaintext = openLedgerEntry(this.keys, log, seq, sealed);
208
+ if (plaintext === undefined) {
209
+ throw new Error(`account ledger entry ${String(seq)} of writer log ${deviceIdToHex(log)} does not open under this account's key`);
210
+ }
211
+ const record = decodeRecord(plaintext);
212
+ if (record !== undefined)
213
+ records.push(record);
214
+ });
215
+ }
216
+ return records;
217
+ }
218
+ }
219
+ /** The record a sealed entry's plaintext holds, or undefined for a record of a later format version than this build knows, written by a newer build on another machine. A record claiming this build's version that does not match its schema throws: it can only be damage. */
220
+ function decodeRecord(plaintext) {
221
+ const decoded = cborDecode(plaintext);
222
+ const probe = versionProbeSchema.parse(decoded);
223
+ if (probe.v !== LEDGER_RECORD_VERSION)
224
+ return undefined;
225
+ return ledgerRecordSchema.parse(decoded);
226
+ }
227
+ /** Feeds every revocation the account ledger holds, and each one another machine's log brings in later, into a store's RevocationView, so a grant any machine of the account revoked is refused there even if the gossiped revocation-announce never reached it. A revocation that fails to verify, or a ledger that cannot be read, is reported rather than recorded. Returns the unsubscribe, for a store that replaces its ledger on joining another account. */
228
+ export function followLedgerRevocations(identity, onError) {
229
+ const report = (error) => {
230
+ onError(error instanceof Error ? error : new Error(String(error)));
231
+ };
232
+ const learn = (entry) => {
233
+ identity.revocation
234
+ .record(entry, { identity: identity.identity })
235
+ .then((verdict) => {
236
+ if (!verdict.ok) {
237
+ report(new Error(`account ledger revocation did not verify: ${verdict.reason}`));
238
+ }
239
+ }, report);
240
+ };
241
+ const unsubscribe = identity.accountLedger.onReplicatedRevocation(learn);
242
+ identity.accountLedger.revocations().then((entries) => {
243
+ entries.forEach(learn);
244
+ }, report);
245
+ return unsubscribe;
246
+ }
247
+ //# sourceMappingURL=account-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-ledger.js","sourceRoot":"","sources":["../../src/core/account-ledger.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-mesh.d.ts","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAMlD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,iSAAiS;IACjS,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,4gBAA4gB;AAC5gB,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;IACrE,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,sSAAsS;AACtS,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CAMhB;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CA8DhB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED,6JAA6J;AAC7J,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAQrB"}
1
+ {"version":3,"file":"bridge-mesh.d.ts","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAMlD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,iSAAiS;IACjS,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED,4gBAA4gB;AAC5gB,MAAM,WAAW,iBAAiB;IAChC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;IACrE,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,sSAAsS;AACtS,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CAMhB;AAED;;GAEG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,cAAc,CAwEhB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED,6JAA6J;AAC7J,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC5B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAQrB"}
@@ -23,6 +23,7 @@ import { FIRST_CONTACT_PORT } from "./first-contact.js";
23
23
  import { CommsTool } from "./tool.js";
24
24
  import { WireMeshTransport } from "./wire-mesh-transport.js";
25
25
  import { loadOrCreateIdentity, oplogDirFor } from "./identity-store.js";
26
+ import { openAccountLedger } from "./account-ledger-store.js";
26
27
  import { toIdentityPort } from "./wire-mesh-identity.js";
27
28
  import { VersionDriftChecker } from "./version-check.js";
28
29
  import { getOwnPackageVersion } from "./package-version.js";
@@ -60,6 +61,10 @@ export function createBridgeMeshSyncFromIdentity(identity, slot, options) {
60
61
  getHostedRooms: () => store.hostedRooms,
61
62
  dataStorage,
62
63
  getSelfAgentAdvert: () => store.selfAgentAdvert,
64
+ accountReplication: {
65
+ getLedger: () => store.accountLedger,
66
+ isAccountMember: async (claim) => store.membership.isAccountMember(claim),
67
+ },
63
68
  gatewayTrust: store.gatewayTrust,
64
69
  });
65
70
  transport.getCcPeerVersion = () => store.getCcPeerVersion?.();
@@ -79,13 +84,19 @@ export function createBridgeMeshSyncFromIdentity(identity, slot, options) {
79
84
  store,
80
85
  tool,
81
86
  attachIdentity: async () => {
87
+ const clock = createSystemClock();
82
88
  store.setIdentity({
83
89
  identity: await toIdentityPort(identity),
84
- clock: createSystemClock(),
90
+ clock,
85
91
  slot,
86
92
  revocation,
87
93
  dataStorage,
88
94
  userIdentity: await toIdentityPort(userIdentity),
95
+ accountLedger: await openAccountLedger({
96
+ userIdentityOptions,
97
+ userIdentity,
98
+ clock,
99
+ }),
89
100
  userIdentityOptions,
90
101
  machineIdentity: await toIdentityPort(machineIdentity),
91
102
  machineIdentityOptions,
@@ -1 +1 @@
1
- {"version":3,"file":"bridge-mesh.js","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bridge-mesh.js","sourceRoot":"","sources":["../../src/core/bridge-mesh.ts"],"names":[],"mappings":"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"}