@serfab/cadre-core 0.8.1 → 0.10.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 (197) hide show
  1. package/README.md +6 -4
  2. package/dist/bootstrap-peer-store-file.d.ts +13 -0
  3. package/dist/bootstrap-peer-store-file.js +42 -0
  4. package/dist/bootstrap-peer-store-file.js.map +1 -0
  5. package/dist/bootstrap-peer-store.d.ts +73 -0
  6. package/dist/bootstrap-peer-store.js +128 -0
  7. package/dist/bootstrap-peer-store.js.map +1 -0
  8. package/dist/cadre-node.d.ts +1006 -101
  9. package/dist/cadre-node.js +1977 -283
  10. package/dist/cadre-node.js.map +1 -1
  11. package/dist/control-authorization.d.ts +93 -0
  12. package/dist/control-authorization.js +57 -0
  13. package/dist/control-authorization.js.map +1 -0
  14. package/dist/control-cohort.d.ts +15 -15
  15. package/dist/control-cohort.js +14 -14
  16. package/dist/control-cohort.js.map +1 -1
  17. package/dist/control-database.d.ts +1033 -76
  18. package/dist/control-database.js +1520 -153
  19. package/dist/control-database.js.map +1 -1
  20. package/dist/control-formation-recorder.d.ts +91 -12
  21. package/dist/control-formation-recorder.js +131 -16
  22. package/dist/control-formation-recorder.js.map +1 -1
  23. package/dist/control-schema.d.ts +1 -1
  24. package/dist/control-schema.js +774 -186
  25. package/dist/control-schema.js.map +1 -1
  26. package/dist/control-stream.d.ts +38 -4
  27. package/dist/control-stream.js +70 -4
  28. package/dist/control-stream.js.map +1 -1
  29. package/dist/control-write-retry.d.ts +151 -0
  30. package/dist/control-write-retry.js +411 -0
  31. package/dist/control-write-retry.js.map +1 -0
  32. package/dist/delegate-admission.d.ts +134 -0
  33. package/dist/delegate-admission.js +244 -0
  34. package/dist/delegate-admission.js.map +1 -0
  35. package/dist/device-token.d.ts +12 -12
  36. package/dist/device-token.js +15 -14
  37. package/dist/device-token.js.map +1 -1
  38. package/dist/ed25519-key.d.ts +68 -0
  39. package/dist/ed25519-key.js +106 -0
  40. package/dist/ed25519-key.js.map +1 -0
  41. package/dist/file-durable-slot.d.ts +20 -0
  42. package/dist/file-durable-slot.js +53 -0
  43. package/dist/file-durable-slot.js.map +1 -0
  44. package/dist/formation-approval.d.ts +157 -0
  45. package/dist/formation-approval.js +375 -0
  46. package/dist/formation-approval.js.map +1 -0
  47. package/dist/fs-atomic.d.ts +38 -0
  48. package/dist/fs-atomic.js +97 -0
  49. package/dist/fs-atomic.js.map +1 -0
  50. package/dist/identity-key.d.ts +49 -0
  51. package/dist/identity-key.js +81 -0
  52. package/dist/identity-key.js.map +1 -0
  53. package/dist/index.d.ts +16 -6
  54. package/dist/index.js +44 -10
  55. package/dist/index.js.map +1 -1
  56. package/dist/key-store-file.d.ts +2 -24
  57. package/dist/key-store-file.js +10 -77
  58. package/dist/key-store-file.js.map +1 -1
  59. package/dist/key-store.d.ts +1 -1
  60. package/dist/key-store.js +1 -1
  61. package/dist/membership-connection-gater.d.ts +146 -0
  62. package/dist/membership-connection-gater.js +180 -0
  63. package/dist/membership-connection-gater.js.map +1 -0
  64. package/dist/node-local-snapshot.d.ts +109 -0
  65. package/dist/node-local-snapshot.js +182 -0
  66. package/dist/node-local-snapshot.js.map +1 -0
  67. package/dist/peer-authorization.d.ts +150 -11
  68. package/dist/peer-authorization.js +170 -13
  69. package/dist/peer-authorization.js.map +1 -1
  70. package/dist/peer-record.d.ts +24 -11
  71. package/dist/peer-record.js +29 -13
  72. package/dist/peer-record.js.map +1 -1
  73. package/dist/push-node.d.ts +38 -0
  74. package/dist/push-node.js +48 -0
  75. package/dist/push-node.js.map +1 -0
  76. package/dist/push-notifier-apns.d.ts +10 -2
  77. package/dist/push-notifier-apns.js +14 -10
  78. package/dist/push-notifier-apns.js.map +1 -1
  79. package/dist/push-notifier-fcm.d.ts +7 -1
  80. package/dist/push-notifier-fcm.js +9 -10
  81. package/dist/push-notifier-fcm.js.map +1 -1
  82. package/dist/push-notifier.d.ts +16 -35
  83. package/dist/push-notifier.js +16 -44
  84. package/dist/push-notifier.js.map +1 -1
  85. package/dist/relay-addrs.d.ts +45 -0
  86. package/dist/relay-addrs.js +103 -0
  87. package/dist/relay-addrs.js.map +1 -0
  88. package/dist/relay-reservation.d.ts +266 -0
  89. package/dist/relay-reservation.js +613 -0
  90. package/dist/relay-reservation.js.map +1 -0
  91. package/dist/seed-bootstrap.d.ts +263 -79
  92. package/dist/seed-bootstrap.js +413 -211
  93. package/dist/seed-bootstrap.js.map +1 -1
  94. package/dist/seed-trust-policy.d.ts +50 -24
  95. package/dist/seed-trust-policy.js +28 -19
  96. package/dist/seed-trust-policy.js.map +1 -1
  97. package/dist/strand-addr-protocol.d.ts +42 -13
  98. package/dist/strand-addr-protocol.js +58 -52
  99. package/dist/strand-addr-protocol.js.map +1 -1
  100. package/dist/strand-backfill.d.ts +109 -0
  101. package/dist/strand-backfill.js +279 -0
  102. package/dist/strand-backfill.js.map +1 -0
  103. package/dist/strand-database.d.ts +5 -5
  104. package/dist/strand-database.js +4 -4
  105. package/dist/strand-database.js.map +1 -1
  106. package/dist/strand-formation-manager.d.ts +38 -9
  107. package/dist/strand-formation-manager.js +120 -17
  108. package/dist/strand-formation-manager.js.map +1 -1
  109. package/dist/strand-formation-protocol.d.ts +104 -5
  110. package/dist/strand-formation-protocol.js +233 -5
  111. package/dist/strand-formation-protocol.js.map +1 -1
  112. package/dist/strand-instance-manager.d.ts +40 -2
  113. package/dist/strand-instance-manager.js +93 -15
  114. package/dist/strand-instance-manager.js.map +1 -1
  115. package/dist/strand-member-key.d.ts +6 -6
  116. package/dist/strand-member-key.js +6 -6
  117. package/dist/strand-member-key.js.map +1 -1
  118. package/dist/strand-member-registry.d.ts +12 -12
  119. package/dist/strand-member-registry.js +22 -14
  120. package/dist/strand-member-registry.js.map +1 -1
  121. package/dist/strand-membership-writer.d.ts +532 -138
  122. package/dist/strand-membership-writer.js +800 -179
  123. package/dist/strand-membership-writer.js.map +1 -1
  124. package/dist/strand-solicitation.d.ts +99 -33
  125. package/dist/strand-solicitation.js +100 -52
  126. package/dist/strand-solicitation.js.map +1 -1
  127. package/dist/strand-transport-key.d.ts +40 -0
  128. package/dist/strand-transport-key.js +56 -0
  129. package/dist/strand-transport-key.js.map +1 -0
  130. package/dist/strand-wake-protocol.d.ts +9 -7
  131. package/dist/strand-wake-protocol.js +22 -46
  132. package/dist/strand-wake-protocol.js.map +1 -1
  133. package/dist/strand-watcher.d.ts +17 -2
  134. package/dist/strand-watcher.js +47 -3
  135. package/dist/strand-watcher.js.map +1 -1
  136. package/dist/trusted-owner-store-file.d.ts +12 -0
  137. package/dist/trusted-owner-store-file.js +39 -0
  138. package/dist/trusted-owner-store-file.js.map +1 -0
  139. package/dist/trusted-owner-store.d.ts +64 -0
  140. package/dist/trusted-owner-store.js +126 -0
  141. package/dist/trusted-owner-store.js.map +1 -0
  142. package/dist/types.d.ts +325 -50
  143. package/dist/types.js +13 -0
  144. package/dist/types.js.map +1 -1
  145. package/package.json +23 -8
  146. package/src/bootstrap-peer-store-file.ts +44 -0
  147. package/src/bootstrap-peer-store.ts +172 -0
  148. package/src/cadre-node.ts +2129 -295
  149. package/src/control-authorization.ts +114 -0
  150. package/src/control-cohort.ts +17 -17
  151. package/src/control-database.ts +1766 -191
  152. package/src/control-formation-recorder.ts +174 -21
  153. package/src/control-schema.ts +786 -198
  154. package/src/control-stream.ts +81 -4
  155. package/src/control-write-retry.ts +473 -0
  156. package/src/delegate-admission.ts +302 -0
  157. package/src/device-token.ts +19 -14
  158. package/src/ed25519-key.ts +134 -0
  159. package/src/file-durable-slot.ts +61 -0
  160. package/src/formation-approval.ts +604 -0
  161. package/src/fs-atomic.ts +107 -0
  162. package/src/identity-key.ts +109 -0
  163. package/src/index.ts +157 -24
  164. package/src/key-store-file.ts +10 -81
  165. package/src/key-store.ts +1 -1
  166. package/src/membership-connection-gater.ts +204 -0
  167. package/src/node-local-snapshot.ts +260 -0
  168. package/src/peer-authorization.ts +219 -13
  169. package/src/peer-record.ts +31 -13
  170. package/src/push-node.ts +64 -0
  171. package/src/push-notifier-apns.ts +16 -12
  172. package/src/push-notifier-fcm.ts +9 -10
  173. package/src/push-notifier.ts +16 -57
  174. package/src/relay-addrs.ts +111 -0
  175. package/src/relay-reservation.ts +823 -0
  176. package/src/seed-bootstrap.ts +490 -226
  177. package/src/seed-trust-policy.ts +65 -32
  178. package/src/strand-addr-protocol.ts +84 -53
  179. package/src/strand-backfill.ts +366 -0
  180. package/src/strand-database.ts +6 -6
  181. package/src/strand-formation-manager.ts +145 -19
  182. package/src/strand-formation-protocol.ts +310 -9
  183. package/src/strand-instance-manager.ts +113 -16
  184. package/src/strand-member-key.ts +7 -7
  185. package/src/strand-member-registry.ts +28 -23
  186. package/src/strand-membership-writer.ts +1430 -640
  187. package/src/strand-solicitation.ts +155 -90
  188. package/src/strand-transport-key.ts +58 -0
  189. package/src/strand-wake-protocol.ts +29 -46
  190. package/src/strand-watcher.ts +66 -3
  191. package/src/trusted-owner-store-file.ts +41 -0
  192. package/src/trusted-owner-store.ts +171 -0
  193. package/src/types.ts +342 -51
  194. package/dist/authority-key.d.ts +0 -41
  195. package/dist/authority-key.js +0 -52
  196. package/dist/authority-key.js.map +0 -1
  197. package/src/authority-key.ts +0 -68
package/dist/types.d.ts CHANGED
@@ -1,15 +1,28 @@
1
1
  import type { ConnectionGater, Libp2p, PeerId, PrivateKey } from '@libp2p/interface';
2
2
  import type { IRawStorage, Libp2pTransports } from '@optimystic/db-p2p';
3
- import type { IRepo } from '@optimystic/db-core';
3
+ import type { IPeerNetwork, IRepo } from '@optimystic/db-core';
4
+ import type { StrandBackfillConfig } from './strand-backfill.js';
4
5
  import type { StrandDatabase } from './strand-database.js';
5
6
  import type { SeedTrustPolicy } from './seed-trust-policy.js';
6
7
  import type { KeyStore, KeyId } from './key-store.js';
8
+ import type { TrustedOwnerStore, TrustSource } from './trusted-owner-store.js';
9
+ import type { BootstrapPeerStore } from './bootstrap-peer-store.js';
10
+ import type { PushNotifier } from './push-notifier.js';
11
+ import type { RevocableTable } from './control-authorization.js';
7
12
  /**
8
13
  * Extended Libp2p node with the coordinatedRepo attached by db-p2p's
9
14
  * createLibp2pNode after node creation (not surfaced on the base Libp2p type).
10
15
  */
11
16
  export interface Libp2pNodeWithRepo extends Libp2p {
12
17
  coordinatedRepo: IRepo;
18
+ /**
19
+ * The node's key-addressed peer network, attached by db-p2p's factory alongside
20
+ * `coordinatedRepo` (`libp2p-node-base.ts`). Optional deliberately: the base
21
+ * factory always assigns it, but it is not part of the upstream node type, so
22
+ * declaring it required would be a claim this repo cannot enforce. The strand
23
+ * backfill (`strand-backfill.ts`) logs once and stays inert when it is absent.
24
+ */
25
+ keyNetwork?: IPeerNetwork;
13
26
  }
14
27
  /**
15
28
  * Node profile determines storage participation
@@ -88,8 +101,9 @@ export interface StorageConfig {
88
101
  *
89
102
  * For React Native, use the appropriate storage from @optimystic/db-p2p-storage-rn:
90
103
  * ```typescript
91
- * import { RNRawStorage } from '@optimystic/db-p2p-storage-rn';
92
- * storage: { provider: (strandId) => new RNRawStorage(strandId) }
104
+ * import { LevelDBRawStorage } from '@optimystic/db-p2p-storage-rn';
105
+ * // `db` is an open LevelDB handle (see `openOptimysticRNDb` over `rn-leveldb`)
106
+ * storage: { provider: (strandId) => new LevelDBRawStorage(openDb(`sereus-${strandId}`)) }
93
107
  * ```
94
108
  *
95
109
  * For in-memory storage (testing):
@@ -106,7 +120,47 @@ export interface StorageConfig {
106
120
  */
107
121
  export interface NetworkConfig {
108
122
  listenAddrs?: string[];
123
+ /**
124
+ * Addresses to advertise to peers instead of `listenAddrs` — for a node behind
125
+ * NAT or a reverse proxy that is reachable at a different address than it binds
126
+ * (e.g. `mynode.example.com:4001` in front of a `0.0.0.0:4001` listener).
127
+ *
128
+ * Accepted (settable in `cadre.yaml`, via `CADRE_ANNOUNCE_ADDRS`, and through the
129
+ * Docker entrypoint) but **not yet applied**: libp2p only takes announce addresses
130
+ * at construction (`addresses.announce` / `addresses.appendAnnounce`), and
131
+ * `@optimystic/db-p2p`'s `NodeOptions` has no field for either — there is nothing
132
+ * in this repo to wire this into. `CadreNode.start()` warns when this is set,
133
+ * rather than pretending it works. Unblocked by the `announce-addrs-option`
134
+ * request filed against `@optimystic/db-p2p`; wiring lands here once this repo's
135
+ * dependency range moves to a version carrying it.
136
+ *
137
+ * Use {@link relayAddrs} for reachability behind NAT today (a reserved relay slot
138
+ * gives the node a real dialable circuit address), or `inviteAddressResolver` to
139
+ * substitute a reachable address into invite payloads specifically — neither
140
+ * changes what this node advertises on the wire, but both cover the operator need
141
+ * this field cannot yet.
142
+ */
109
143
  announceAddrs?: string[];
144
+ /**
145
+ * Circuit-relay servers this node reserves a slot on, so peers can reach it
146
+ * from behind NAT. Each entry is the relay's DIRECT dial multiaddr ending in
147
+ * its peerId — `/dns4/relay.example.com/tcp/4001/p2p/12D3KooW…` — with no
148
+ * `/p2p-circuit` suffix (one is appended for you; an entry that already has
149
+ * one is passed through unchanged).
150
+ *
151
+ * This is sugar for a circuit entry in {@link listenAddrs}: `relay-addrs.ts`
152
+ * resolves the two into one listen list, and listening on a relay's circuit
153
+ * addr is what makes libp2p dial it and hold the reservation. A relay named
154
+ * here therefore also becomes a delegate-announce target, so this node's
155
+ * strand nodes may reserve on it too (see `delegate-admission.ts`).
156
+ *
157
+ * Setting this gives the node a listener even when `listenAddrs` is `[]` —
158
+ * that is the point of naming a relay, but note that React Native hosts
159
+ * (`reference-app-rn`'s `cadre-phone.ts`) deliberately do NOT listen, and
160
+ * must not acquire a listener by accident.
161
+ *
162
+ * A malformed entry throws at node start rather than being silently dropped.
163
+ */
110
164
  relayAddrs?: string[];
111
165
  /**
112
166
  * Enable circuit relay server - allows this node to relay connections for other peers.
@@ -133,7 +187,7 @@ export interface NetworkConfig {
133
187
  transports?: Libp2pTransports;
134
188
  /**
135
189
  * Optional async resolver returning the multiaddrs to embed in invites
136
- * (and other authority-address contexts). When unset, `libp2pNode.getMultiaddrs()`
190
+ * (and other owner-address contexts). When unset, `libp2pNode.getMultiaddrs()`
137
191
  * is used. Hosts behind NAT supply this to substitute their DDNS hostname
138
192
  * and externally-mapped port — see `@serfab/cadre-host`'s NatService.
139
193
  */
@@ -146,6 +200,12 @@ export interface NetworkConfig {
146
200
  * Playwright e2e, RN simulators) supply a permissive gater here — e.g.
147
201
  * `{ denyDialMultiaddr: () => false }`. See `@optimystic/db-p2p`'s
148
202
  * `libp2p-node-base` for the underlying option.
203
+ *
204
+ * On the CONTROL node this gater is composed with the built-in membership
205
+ * admission gate (`membership-connection-gater.ts`): every hook supplied here
206
+ * is honored unchanged, and on inbound encrypted connections a deny from
207
+ * either this gater or the membership policy denies. Strand cohort nodes
208
+ * receive this gater as-is (their peers are legitimately cross-party).
149
209
  */
150
210
  connectionGater?: ConnectionGater;
151
211
  /**
@@ -158,8 +218,8 @@ export interface NetworkConfig {
158
218
  */
159
219
  controlCohort?: {
160
220
  /**
161
- * Cap on the number of NON-authority siblings dialed per reconcile pass
162
- * (backbone/authority members are always dialed and do not count). Defaults
221
+ * Cap on the number of NON-owner siblings dialed per reconcile pass
222
+ * (backbone/owner members are always dialed and do not count). Defaults
163
223
  * to {@link DEFAULT_CONTROL_COHORT_TARGET_DEGREE}.
164
224
  */
165
225
  targetDegree?: number;
@@ -200,6 +260,19 @@ export interface ControlNetworkConfig {
200
260
  /** Optional path to the control schema file (defaults to bundled schema) */
201
261
  schemaPath?: string;
202
262
  }
263
+ /**
264
+ * Replication-breadth constants, both networks' cluster policies, and the strand
265
+ * resolver, re-exported so cadre embedders, the SQL plugin and the integration
266
+ * harness share one definition. Defined in `@serfab/quereus-plugin-sereus`
267
+ * because that package also creates libp2p nodes and cannot depend on this one.
268
+ * The control network's breadth is fixed ({@link CONTROL_REPLICATION_BREADTH},
269
+ * not configurable) and so is its consensus policy ({@link CONTROL_CLUSTER_POLICY}
270
+ * — notably the super-majority threshold, which it leaves at Optimystic's default
271
+ * by omission); the strand breadth defaults to
272
+ * {@link CadreNodeConfig.strandClusterSize} while its policy is the fixed
273
+ * {@link STRAND_CLUSTER_POLICY}.
274
+ */
275
+ export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize } from '@serfab/quereus-plugin-sereus';
203
276
  /**
204
277
  * Main configuration for a CadreNode
205
278
  */
@@ -217,10 +290,10 @@ export interface CadreNodeConfig {
217
290
  * form). Mutually exclusive with {@link privateKey}. Absent ⇒ legacy behavior
218
291
  * (use `privateKey`, else libp2p generates an ephemeral key).
219
292
  *
220
- * In the single-key reference model the authority signing key is *derived from*
221
- * the node identity (see {@link CadreNode.getIdentityAuthorityKey}), so
222
- * protecting the identity in a secure enclave protects the authority key too.
223
- * A future separate-authority slot (`authorityKeyId`) is anticipated but not
293
+ * In the single-key reference model the owner signing key is *derived from*
294
+ * the node identity (see {@link CadreNode.getIdentityOwnerKey}), so
295
+ * protecting the identity in a secure enclave protects the owner key too.
296
+ * A future separate-owner slot (`ownerKeyId`) is anticipated but not
224
297
  * built here.
225
298
  */
226
299
  keyStore?: KeyStore;
@@ -236,6 +309,41 @@ export interface CadreNodeConfig {
236
309
  storage?: StorageConfig;
237
310
  /** Network configuration */
238
311
  network?: NetworkConfig;
312
+ /**
313
+ * Number of nodes Optimystic is told a **strand** network's replication cluster
314
+ * should have, for every strand this node starts. The control network is not
315
+ * configurable — it always replicates to {@link CONTROL_REPLICATION_BREADTH}
316
+ * nodes, which is above any party's node count, because every member reads the
317
+ * whole control database and a member that misses a write may never learn the
318
+ * fact (see that constant for the full reasoning).
319
+ *
320
+ * Every node on the same strand should use the same value: the number bounds the
321
+ * cohort a member independently derives, and Optimystic's cluster-membership gate
322
+ * can reject a coordinator's smaller declared set as a downsize against a larger
323
+ * derived view.
324
+ *
325
+ * Frozen when the strand's libp2p node is created; a change takes effect on
326
+ * restart, not when cadre membership grows. Defaults to
327
+ * {@link DEFAULT_STRAND_CLUSTER_SIZE} (4 — the smallest breadth whose 0.75
328
+ * super-majority still commits with one holder offline); anything below
329
+ * {@link MIN_CLUSTER_SIZE} is rejected before a node is created. The cost of a
330
+ * small value is replication breadth and reliance on read repair, not commit
331
+ * correctness — but at 2 that read repair cannot converge, because a lone
332
+ * corroborator's stale answer is accepted as the cluster's truth.
333
+ */
334
+ strandClusterSize?: number;
335
+ /**
336
+ * Tuning for the strand peer-join block catch-up (see `strand-backfill.ts`):
337
+ * when a strand's libp2p node connects to a peer this runtime has not yet
338
+ * caught up, every block in the strand's own raw store is pushed to that peer,
339
+ * so a machine that joined the strand after blocks were committed still ends
340
+ * up physically holding them. Applies to every strand this node starts;
341
+ * strand-only — the control network has its own row-level re-issue queue
342
+ * (`drainPendingControlReplication`). Omit for the defaults
343
+ * (`DEFAULT_STRAND_BACKFILL`); `{ enabled: false }` restores the
344
+ * no-backfill behaviour.
345
+ */
346
+ strandBackfill?: StrandBackfillConfig;
239
347
  /** Hibernation configuration */
240
348
  hibernation?: HibernationConfig;
241
349
  /** Polling interval for strand watcher in ms (default: 5000) */
@@ -249,24 +357,103 @@ export interface CadreNodeConfig {
249
357
  requireSignedSchemas?: boolean;
250
358
  /**
251
359
  * Node-wide default trust anchor for INBOUND control-network seeds. Forwarded
252
- * into every SeedBootstrapService this node constructs (authority, receive-only
360
+ * into every SeedBootstrapService this node constructs (owner, receive-only
253
361
  * listener, and the temp service used by applySeed when no service exists), and
254
362
  * used as the service-level default the libp2p seed-protocol handler relies on
255
- * (that path has no per-call override seam). Defaults to dbAnchoredTrustPolicy()
256
- * inside SeedBootstrapService when unset — a cold-start node then rejects every
257
- * seed. A per-call `applySeed(seed, { trustPolicy })` override still wins over
258
- * this default for callers that hold out-of-band material (e.g. a pinned key
259
- * from a CadreInvite).
363
+ * (that path has no per-call override seam). Defaults to anchoredTrustPolicy()
364
+ * inside SeedBootstrapService when unset — a node whose node-local trusted-owner
365
+ * anchor was never seeded then rejects every seed. A per-call
366
+ * `applySeed(seed, { trustPolicy })` override still wins over this default for
367
+ * callers that hold out-of-band material (e.g. a pinned key from a CadreInvite).
260
368
  */
261
369
  seedTrustPolicy?: SeedTrustPolicy;
262
370
  /**
263
- * Platform push-delivery credentials (FCM and/or APNs). When present, the node
264
- * can deliver strand-wake data messages to suspended mobile peers over the
265
- * platform push channel — the server fan-out constructs a `PushNotifier` from
266
- * this. Absent ⇒ no platform push (control-network push-wake only). Injected
267
- * per node by `cadre-host`; `privateKey` fields are secrets and are never logged.
371
+ * Node-local trusted-owner anchor (see `trusted-owner-store.ts`): the
372
+ * NON-replicated, per-party record of owner keys established out of band —
373
+ * the anchor membership/seed trust can rest on, since the replicated
374
+ * `OwnerKey` table can be polluted by a stranger's self-genesis. Absent ⇒ an
375
+ * in-memory store is created at start() (ephemeral: anchored trust does not
376
+ * survive the process).
377
+ */
378
+ trustedOwners?: {
379
+ /**
380
+ * Injected store instance — e.g. a `FileTrustedOwnerStore` from the
381
+ * Node-only subpath `@serfab/cadre-core/trusted-owner-store-file`,
382
+ * persisted in the node's state directory (same injection/isolation pattern
383
+ * as {@link keyStore}). Its `partyId` must match `controlNetwork.partyId`;
384
+ * start() fails closed on a mismatch.
385
+ */
386
+ store?: TrustedOwnerStore;
387
+ /**
388
+ * Owner keys (base64url ed25519) established out of band and seeded into
389
+ * the store during start(): operator pins (e.g. cadre-cli
390
+ * `--pin-owner-key` / `CADRE_OWNER_KEYS`) or a `CadreInvite.ownerKeys`
391
+ * already known at config time. Seeding is idempotent across restarts.
392
+ */
393
+ pinnedKeys?: string[];
394
+ /**
395
+ * Provenance recorded for {@link pinnedKeys}. Default: 'operator'.
396
+ * ('genesis' is reserved for the node's own founding key, seeded
397
+ * internally by `initializeSeedBootstrap`.)
398
+ */
399
+ pinnedSource?: Exclude<TrustSource, 'genesis'>;
400
+ };
401
+ /**
402
+ * Node-local cold-start bootstrap-peer store (see `bootstrap-peer-store.ts`):
403
+ * the owner addresses an applied seed nominated, kept so
404
+ * `reconcileControlCohort`'s cold-start branch can keep retrying a node that
405
+ * was seeded but never managed to connect. Sibling of {@link trustedOwners} —
406
+ * same NON-replicated, per-party, injected-backend shape — but nothing here is
407
+ * trust-bearing: these are dial hints only, and every address is re-bound to
408
+ * its peer id before the dial. Absent ⇒ an in-memory store is created at
409
+ * start() (ephemeral: the retry set does not survive the process, and such a
410
+ * node is stranded permanently if it restarts before connecting).
411
+ *
412
+ * The Node CLI, the browser, and React Native all inject a durable backend
413
+ * today; only NativeScript stays ephemeral, tracked by the
414
+ * `ns-durable-node-local-stores` ticket (which covers the same gap for
415
+ * {@link trustedOwners}). A new platform needs no new store class: supply a
416
+ * `DurableSlot` for the platform's storage and inject
417
+ * `PersistentBootstrapPeerStore.open(slot, partyId)` /
418
+ * `PersistentTrustedOwnerStore.open(slot, partyId)`.
419
+ */
420
+ bootstrapPeers?: {
421
+ /**
422
+ * Injected store instance — e.g. a `FileBootstrapPeerStore` from the
423
+ * Node-only subpath `@serfab/cadre-core/bootstrap-peer-store-file`, persisted
424
+ * in the node's state directory (same injection/isolation pattern as
425
+ * {@link keyStore} / {@link trustedOwners}). Its `partyId` must match
426
+ * `controlNetwork.partyId`; start() fails closed on a mismatch.
427
+ */
428
+ store?: BootstrapPeerStore;
429
+ };
430
+ /**
431
+ * Platform push-delivery for suspended mobile peers. When present, the node's
432
+ * server fan-out can deliver strand-wake data messages over the platform push
433
+ * channel (FCM/APNs). Absent ⇒ no platform push (control-network push-wake only).
434
+ *
435
+ * The `notifier` is **injected**, not constructed here: a Node host builds it
436
+ * from `@serfab/cadre-core/push-node` (`createPushNotifier(credentials)`) and
437
+ * passes the instance, so the FCM/APNs modules (`node:crypto`/`node:http2`)
438
+ * stay out of the cross-platform core graph. Ownership transfers to the node on
439
+ * injection — `CadreNode.stop` closes the notifier (via `PushFanoutService`),
440
+ * releasing its APNs HTTP/2 session; a host must NOT also close an injected
441
+ * notifier itself. `cooldownMs`/`debounceMs` carry the fan-out anti-spam policy.
268
442
  */
269
- push?: PushCredentials;
443
+ push?: {
444
+ /** The Node-constructed push router (see `@serfab/cadre-core/push-node`). */
445
+ notifier: PushNotifier;
446
+ /**
447
+ * Per-`(peer, strand)` minimum gap between push-wakes the fan-out emits.
448
+ * Default {@link DEFAULT_PUSH_COOLDOWN_MS} (5 min).
449
+ */
450
+ cooldownMs?: number;
451
+ /**
452
+ * Per-strand burst-coalescing window: a second trigger within it is dropped.
453
+ * Default {@link DEFAULT_PUSH_DEBOUNCE_MS} (10 s).
454
+ */
455
+ debounceMs?: number;
456
+ };
270
457
  }
271
458
  /**
272
459
  * Status of a strand instance
@@ -288,6 +475,13 @@ export interface StrandInstance {
288
475
  strandId: string;
289
476
  status: StrandStatus;
290
477
  sAppInfo?: SAppInfo;
478
+ /**
479
+ * The lifecycle mode this instance's runtime was built with — `bootstrap`
480
+ * (purely local transactor) or `networked` (cluster transactor). Refreshed on
481
+ * every runtime (re)build, so a resume that shifts `bootstrap → networked`
482
+ * updates it. Read-only reporting; drives no behavior.
483
+ */
484
+ mode: StrandMode;
291
485
  /** The libp2p node for this strand (only when active/idle) */
292
486
  libp2pNode?: Libp2p;
293
487
  /** The Quereus database for this strand (only when active/idle) */
@@ -389,7 +583,7 @@ export interface StrandConfig {
389
583
  * published the strand (the responder in formation, the creator in host/solo
390
584
  * paths; the same party that calls {@link CadreNode.publishStrand}). The founder
391
585
  * runs the one-time membership bootstrap at bring-up (writes `Strand.Header`, and
392
- * for a closed strand the founding `Member`+`Authority`). A joiner leaves this
586
+ * for a closed strand the founding `Member`+`Manager`). A joiner leaves this
393
587
  * `false`/unset and writes nothing — it receives those rows via Optimystic sync.
394
588
  * Defaults to `false`.
395
589
  */
@@ -453,15 +647,6 @@ export interface FormStrandResult {
453
647
  */
454
648
  memberPrivateKey?: string;
455
649
  }
456
- /**
457
- * Result of validating a strand formation request
458
- */
459
- export interface ValidateFormationResult {
460
- /** Public key for validating this formation */
461
- validationKey: string;
462
- /** Signature over the formation approval */
463
- validationSignature: string;
464
- }
465
650
  /**
466
651
  * Disclosure object provided during strand formation.
467
652
  * Contains identity and context information from the initiator.
@@ -569,13 +754,57 @@ export interface PeerAddressRecord {
569
754
  /** ed25519 self-signature over the signed payload, base64url. */
570
755
  sig: string;
571
756
  }
757
+ /**
758
+ * One `CadreControl.CadrePeer` row as read by `ControlDatabase.queryCadrePeers`:
759
+ * the addressing columns plus the persisted membership voucher.
760
+ *
761
+ * The voucher triple (`stampId`, `vouchOwner`, `vouchSig`) is what
762
+ * {@link CadreNode.listAuthorizedMembers} re-checks against the node-local
763
+ * trusted-owner anchor — it is null on a row written before the voucher columns
764
+ * existed, and all three must be present for the row to be authorizable. Named
765
+ * (rather than restated inline at each read site) so a future column addition
766
+ * cannot reach the query without the predicate seeing it.
767
+ */
768
+ export interface CadrePeerRow {
769
+ /** libp2p peer ID (base58btc) — the row key. */
770
+ peerId: string;
771
+ /** Comma-joined dialable multiaddrs as stored, or null when unpublished. */
772
+ multiaddr: string | null;
773
+ /** Single-use anti-replay nonce the voucher signature is bound to. */
774
+ stampId: string | null;
775
+ /** ed25519 public key (base64url) of the owner that vouched this row. */
776
+ vouchOwner: string | null;
777
+ /** That owner's signature over `digest('CadreControl.CadrePeer', 'vouch', peerId, stampId)`, base64url. */
778
+ vouchSig: string | null;
779
+ }
780
+ /** The voucher-bearing subset of a {@link CadrePeerRow} — what the authorized-membership predicate reads. */
781
+ export type CadrePeerVoucherFields = Pick<CadrePeerRow, 'peerId' | 'stampId' | 'vouchOwner' | 'vouchSig'>;
782
+ /**
783
+ * One `CadreControl.Revocation` tombstone as read by
784
+ * `ControlDatabase.queryRevocations`: the identity triple plus the `ReissuedAt`
785
+ * counter an owner bumps (`ControlDatabase.reissueRevocations`) to re-write — and
786
+ * therefore re-broadcast — a tombstone that committed while the node was alone.
787
+ */
788
+ export interface RevocationRow {
789
+ /** Which guarded table's stamp was retired. */
790
+ tableName: RevocableTable;
791
+ /** Primary key of the removed row (peer id / key / strand id). */
792
+ rowKey: string;
793
+ /** The retired single-use nonce — the tombstone's identity. */
794
+ stampId: string;
795
+ /** Monotonic re-issue counter; carries no semantics (see the schema comment). */
796
+ reissuedAt: number;
797
+ }
572
798
  /**
573
799
  * Outcome of {@link CadreNode.registerSelf}, surfaced so callers (e.g. the CLI
574
- * `--authority` branch) can log what happened:
575
- * - `inserted` — the first authority-signed INSERT of this node's `CadrePeer` row.
800
+ * `--owner` branch) can log what happened:
801
+ * - `inserted` — the first owner-signed INSERT of this node's `CadrePeer` row.
576
802
  * - `refreshed` — a self-signed UPDATE of an existing row (heartbeat / addr change).
577
- * - `skipped` — nothing written (no self-signing key, or not yet a member with no
578
- * authority service to self-insert).
803
+ * Also reported when a first publish found its row seated by a concurrent
804
+ * `authorizePeer` of this node's own id and fell through to the UPDATE — the write
805
+ * really was an UPDATE, even though the caller's intent was a first publish.
806
+ * - `skipped` — nothing written (no self-signing key, not yet a member with no
807
+ * owner service to self-insert, or the row was removed mid-publish).
579
808
  */
580
809
  export type SelfRegistrationOutcome = 'inserted' | 'refreshed' | 'skipped';
581
810
  /**
@@ -593,7 +822,7 @@ export interface ResolveOpts {
593
822
  /**
594
823
  * Pluggable trust gate, evaluated after signature + freshness pass. Defaults
595
824
  * to {@link currentMemberTrustPolicy} (any existing — therefore
596
- * authority-vouched — CadrePeer member is trusted). Inject a stricter policy
825
+ * owner-vouched — CadrePeer member is trusted). Inject a stricter policy
597
826
  * (e.g. from `seed-signerkey-trust-policy`) to reject otherwise-valid records
598
827
  * before dialing.
599
828
  */
@@ -648,6 +877,20 @@ export interface DeviceTokenRecord {
648
877
  /** ed25519 self-signature over the signed payload, base64url. */
649
878
  sig: string;
650
879
  }
880
+ /**
881
+ * A stored `CadreControl.DeviceToken` row: the self-signed
882
+ * {@link DeviceTokenRecord} plus the row's single-use `StampId` nonce.
883
+ *
884
+ * The stamp is deliberately OUTSIDE `DeviceTokenRecord`: the peer's own `Sig`
885
+ * covers only (peerId, platform, token, updatedAt), while the stamp is bound by
886
+ * the OWNER's insert/delete approvals. Readers need it to drop a row whose stamp
887
+ * has been retired into `CadreControl.Revocation` (a token resurrected by an
888
+ * approval replay on a node that had not yet converged on the tombstone).
889
+ */
890
+ export interface DeviceTokenRow extends DeviceTokenRecord {
891
+ /** Single-use authorization nonce; rotates on every (re)insert. */
892
+ stampId: string;
893
+ }
651
894
  /**
652
895
  * Options for {@link CadreNode.resolveDeviceToken}.
653
896
  */
@@ -720,9 +963,9 @@ export interface SeedPeer {
720
963
  peerId: string;
721
964
  /** Multiaddrs for connecting to this peer */
722
965
  multiaddrs: string[];
723
- /** Whether this peer holds an authority key */
724
- isAuthority: boolean;
725
- /** ed25519 public key (base64url) — present on authority peers for signerKey verification */
966
+ /** Whether this peer holds an owner key */
967
+ isOwner: boolean;
968
+ /** ed25519 public key (base64url) — present on owner peers for signerKey verification */
726
969
  publicKey?: string;
727
970
  }
728
971
  /**
@@ -736,9 +979,9 @@ export interface ControlNetworkSeed {
736
979
  partyId: string;
737
980
  /** Known peers in the cadre */
738
981
  peers: SeedPeer[];
739
- /** Signature over the seed by an authority key */
982
+ /** Signature over the seed by an owner key */
740
983
  signature: string;
741
- /** The authority key that signed this seed */
984
+ /** The owner key that signed this seed */
742
985
  signerKey: string;
743
986
  }
744
987
  /**
@@ -750,9 +993,9 @@ export interface SeedMessage {
750
993
  partyId: string;
751
994
  /** Known peers in the cadre */
752
995
  peers: SeedPeer[];
753
- /** Signature by an authority key */
996
+ /** Signature by an owner key */
754
997
  signature: string;
755
- /** The authority key that signed this message */
998
+ /** The owner key that signed this message */
756
999
  signerKey: string;
757
1000
  }
758
1001
  /**
@@ -795,6 +1038,14 @@ export interface WakeAck {
795
1038
  export interface StrandAddrRequest {
796
1039
  /** The strand whose strand-network address the requester wants to seed from. */
797
1040
  strandId: string;
1041
+ /**
1042
+ * The derived transport peerId the requester's own strand-`strandId` node
1043
+ * runs as (see `strand-transport-key.ts`). Present → the responder records a
1044
+ * delegate admission grant for it, so its own connection gate (and thus its
1045
+ * circuit-relay server, when it runs one) admits that peerId; absent →
1046
+ * today's behavior exactly. See `delegate-admission.ts` for the trust model.
1047
+ */
1048
+ delegatePeerId?: string;
798
1049
  }
799
1050
  /**
800
1051
  * Response to a {@link StrandAddrRequest}, carrying the responder's strand-node
@@ -829,6 +1080,27 @@ export interface ApplySeedResult {
829
1080
  peersAdded: number;
830
1081
  /** Error message if not successful */
831
1082
  error?: string;
1083
+ /**
1084
+ * Owner-flagged seed peers this apply attempted to dial. Zero when the seed
1085
+ * carried no owner peer with an address, or when the seed was rejected before
1086
+ * the dial loop ran.
1087
+ */
1088
+ ownerDialsAttempted: number;
1089
+ /**
1090
+ * How many of those dials threw. `ownerDialsAttempted > 0 && ownerDialsFailed
1091
+ * === ownerDialsAttempted` means "seeded but stranded": the seed itself was
1092
+ * accepted (`success: true`) but no owner could be reached, so this node has
1093
+ * no connection to bootstrap its control database from. The node retries those
1094
+ * addresses on every control-cohort reconcile pass (see
1095
+ * `CadreNode.dialColdStartBootstrap`), so this is a signal, not a fatal error.
1096
+ *
1097
+ * Zero failures is NOT proof of a live connection: the receiving node's
1098
+ * membership gate denies AFTER the dialer's upgrade completes (see
1099
+ * `createMembershipConnectionGater`), so a dial can resolve and then be torn
1100
+ * down. Treat a non-zero value as certain failure and zero as "no failure
1101
+ * observed".
1102
+ */
1103
+ ownerDialsFailed: number;
832
1104
  }
833
1105
  /**
834
1106
  * Node network topology type for seed helper scenarios.
@@ -841,15 +1113,18 @@ export type NodeTopology = 'public' | 'nat';
841
1113
  export interface CadreInvite {
842
1114
  /** Party ID of the cadre */
843
1115
  partyId: string;
844
- /** Multiaddrs to dial the authority */
845
- authorityAddrs: string[];
1116
+ /** Multiaddrs to dial the owner */
1117
+ ownerAddrs: string[];
846
1118
  /**
847
- * Authority ed25519 public keys (base64url) of the cadre, carried out-of-band
848
- * so a cold-start invitee can pin the trusted authority set before applying
1119
+ * Owner ed25519 public keys (base64url) of the cadre, carried out-of-band
1120
+ * so a cold-start invitee can pin the trusted owner set before applying
849
1121
  * any seed (the seed itself cannot vouch for its own signer). Populated by
850
- * `createInvite` from the issuer's `AuthorityKey` table.
1122
+ * `createInvite` from the issuer's OWN node-local trusted-owner anchor —
1123
+ * not its replicated `OwnerKey` table, because the invitee anchors whatever
1124
+ * arrives here and a stranger's genesis-inserted key must not ride an
1125
+ * otherwise-legitimate invite into a fresh node's anchor.
851
1126
  */
852
- authorityKeys?: string[];
1127
+ ownerKeys?: string[];
853
1128
  /** Optional invite token for validation */
854
1129
  token?: string;
855
1130
  /** Timestamp when invite was created */
package/dist/types.js CHANGED
@@ -40,4 +40,17 @@ export const HIBERNATION_TIMEOUTS = {
40
40
  * See {@link HibernationConfig.checkInWindowMs}.
41
41
  */
42
42
  export const DEFAULT_CHECKIN_WINDOW_MS = 15 * 1000;
43
+ /**
44
+ * Replication-breadth constants, both networks' cluster policies, and the strand
45
+ * resolver, re-exported so cadre embedders, the SQL plugin and the integration
46
+ * harness share one definition. Defined in `@serfab/quereus-plugin-sereus`
47
+ * because that package also creates libp2p nodes and cannot depend on this one.
48
+ * The control network's breadth is fixed ({@link CONTROL_REPLICATION_BREADTH},
49
+ * not configurable) and so is its consensus policy ({@link CONTROL_CLUSTER_POLICY}
50
+ * — notably the super-majority threshold, which it leaves at Optimystic's default
51
+ * by omission); the strand breadth defaults to
52
+ * {@link CadreNodeConfig.strandClusterSize} while its policy is the fixed
53
+ * {@link STRAND_CLUSTER_POLICY}.
54
+ */
55
+ export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize } from '@serfab/quereus-plugin-sereus';
43
56
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA8DA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC5E,QAAQ,EAAE;QACR,WAAW,EAAE,QAAQ,EAAS,aAAa;QAC3C,gBAAgB,EAAE,QAAQ,EAAI,kBAAkB;QAChD,eAAe,EAAE,QAAQ,EAAK,MAAM;QACpC,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,QAAQ,CAAE,MAAM;KACrC;IACD,WAAW,EAAE;QACX,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,YAAY;QAC1C,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,wBAAwB;QAC1D,eAAe,EAAE,EAAE,GAAG,IAAI,EAAI,mBAAmB;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KACnD;IACD,UAAU,EAAE;QACV,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,WAAW;QACzC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,uBAAuB;QACzD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,kBAAkB;QACpD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB;KACxD;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,GAAG,IAAI,EAAQ,aAAa;QAC3C,gBAAgB,EAAE,EAAE,GAAG,IAAI,EAAG,wBAAwB;QACtD,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,eAAe;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KAC5D;CACF,CAAC;AA4HF;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA2EA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC5E,QAAQ,EAAE;QACR,WAAW,EAAE,QAAQ,EAAS,aAAa;QAC3C,gBAAgB,EAAE,QAAQ,EAAI,kBAAkB;QAChD,eAAe,EAAE,QAAQ,EAAK,MAAM;QACpC,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,QAAQ,CAAE,MAAM;KACrC;IACD,WAAW,EAAE;QACX,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,YAAY;QAC1C,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,wBAAwB;QAC1D,eAAe,EAAE,EAAE,GAAG,IAAI,EAAI,mBAAmB;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KACnD;IACD,UAAU,EAAE;QACV,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,WAAW;QACzC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,uBAAuB;QACzD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,kBAAkB;QACpD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB;KACxD;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,GAAG,IAAI,EAAQ,aAAa;QAC3C,gBAAgB,EAAE,EAAE,GAAG,IAAI,EAAG,wBAAwB;QACtD,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,eAAe;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KAC5D;CACF,CAAC;AA2KF;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC;AAYnD;;;;;;;;;;;GAWG;AACH,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,+BAA+B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serfab/cadre-core",
3
- "version": "0.8.1",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "description": "Core library for Sereus cadre nodes - manages control networks and strand participation",
6
6
  "main": "dist/index.js",
@@ -23,6 +23,18 @@
23
23
  "./key-store-file": {
24
24
  "types": "./dist/key-store-file.d.ts",
25
25
  "import": "./dist/key-store-file.js"
26
+ },
27
+ "./trusted-owner-store-file": {
28
+ "types": "./dist/trusted-owner-store-file.d.ts",
29
+ "import": "./dist/trusted-owner-store-file.js"
30
+ },
31
+ "./bootstrap-peer-store-file": {
32
+ "types": "./dist/bootstrap-peer-store-file.d.ts",
33
+ "import": "./dist/bootstrap-peer-store-file.js"
34
+ },
35
+ "./push-node": {
36
+ "types": "./dist/push-node.d.ts",
37
+ "import": "./dist/push-node.js"
26
38
  }
27
39
  },
28
40
  "repository": {
@@ -50,8 +62,11 @@
50
62
  "devDependencies": {
51
63
  "@chainsafe/libp2p-noise": "^17.0.0",
52
64
  "@chainsafe/libp2p-yamux": "^8.0.1",
53
- "@libp2p/peer-id-factory": "^4.2.4",
65
+ "@libp2p/circuit-relay-v2": "^4.1.3",
66
+ "@libp2p/identify": "4.0.10",
54
67
  "@libp2p/tcp": "^11.0.10",
68
+ "@libp2p/webrtc": "6.0.14",
69
+ "@libp2p/websockets": "^10.1.3",
55
70
  "@types/debug": "^4.1.12",
56
71
  "@types/node": "^25.0.10",
57
72
  "@vitest/coverage-v8": "^4.0.17",
@@ -64,12 +79,12 @@
64
79
  "@libp2p/interface": "^3.1.0",
65
80
  "@libp2p/peer-id": "^6.0.4",
66
81
  "@multiformats/multiaddr": "^12.5.1",
67
- "@optimystic/db-core": "^0.14.1",
68
- "@optimystic/db-p2p": "^0.14.1",
69
- "@optimystic/quereus-plugin-crypto": "^0.14.1",
70
- "@optimystic/quereus-plugin-optimystic": "^0.14.1",
71
- "@quereus/quereus": "^4.2.1",
72
- "@serfab/quereus-plugin-sereus": "^0.8.1",
82
+ "@optimystic/db-core": "^0.22.0",
83
+ "@optimystic/db-p2p": "^0.22.0",
84
+ "@optimystic/quereus-plugin-crypto": "^0.22.0",
85
+ "@optimystic/quereus-plugin-optimystic": "^0.22.0",
86
+ "@quereus/quereus": "^4.10.0",
87
+ "@serfab/quereus-plugin-sereus": "^0.10.0",
73
88
  "debug": "^4.4.3",
74
89
  "libp2p": "^3.1.3",
75
90
  "uint8arrays": "^5.1.0"