@serfab/cadre-core 0.0.2

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 (54) hide show
  1. package/README.md +252 -0
  2. package/dist/arachnode-stub.d.ts +60 -0
  3. package/dist/arachnode-stub.js +120 -0
  4. package/dist/arachnode-stub.js.map +1 -0
  5. package/dist/cadre-node.d.ts +252 -0
  6. package/dist/cadre-node.js +753 -0
  7. package/dist/cadre-node.js.map +1 -0
  8. package/dist/control-database.d.ts +62 -0
  9. package/dist/control-database.js +295 -0
  10. package/dist/control-database.js.map +1 -0
  11. package/dist/enrollment.d.ts +76 -0
  12. package/dist/enrollment.js +126 -0
  13. package/dist/enrollment.js.map +1 -0
  14. package/dist/hibernation-manager.d.ts +68 -0
  15. package/dist/hibernation-manager.js +212 -0
  16. package/dist/hibernation-manager.js.map +1 -0
  17. package/dist/index.d.ts +12 -0
  18. package/dist/index.js +24 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/seed-bootstrap.d.ts +164 -0
  21. package/dist/seed-bootstrap.js +554 -0
  22. package/dist/seed-bootstrap.js.map +1 -0
  23. package/dist/strand-database.d.ts +39 -0
  24. package/dist/strand-database.js +108 -0
  25. package/dist/strand-database.js.map +1 -0
  26. package/dist/strand-formation-manager.d.ts +87 -0
  27. package/dist/strand-formation-manager.js +168 -0
  28. package/dist/strand-formation-manager.js.map +1 -0
  29. package/dist/strand-instance-manager.d.ts +60 -0
  30. package/dist/strand-instance-manager.js +209 -0
  31. package/dist/strand-instance-manager.js.map +1 -0
  32. package/dist/strand-solicitation.d.ts +145 -0
  33. package/dist/strand-solicitation.js +180 -0
  34. package/dist/strand-solicitation.js.map +1 -0
  35. package/dist/strand-watcher.d.ts +70 -0
  36. package/dist/strand-watcher.js +136 -0
  37. package/dist/strand-watcher.js.map +1 -0
  38. package/dist/types.d.ts +484 -0
  39. package/dist/types.js +26 -0
  40. package/dist/types.js.map +1 -0
  41. package/package.json +67 -0
  42. package/src/arachnode-stub.ts +160 -0
  43. package/src/cadre-node.ts +923 -0
  44. package/src/control-database.ts +376 -0
  45. package/src/enrollment.ts +199 -0
  46. package/src/hibernation-manager.ts +268 -0
  47. package/src/index.ts +71 -0
  48. package/src/seed-bootstrap.ts +753 -0
  49. package/src/strand-database.ts +168 -0
  50. package/src/strand-formation-manager.ts +277 -0
  51. package/src/strand-instance-manager.ts +281 -0
  52. package/src/strand-solicitation.ts +318 -0
  53. package/src/strand-watcher.ts +197 -0
  54. package/src/types.ts +553 -0
@@ -0,0 +1,554 @@
1
+ import debug from 'debug';
2
+ import { toString as uint8ArrayToString, fromString as uint8ArrayFromString } from 'uint8arrays';
3
+ import { digest, sign, verify, getPublicKey } from '@optimystic/quereus-plugin-crypto';
4
+ import { multiaddr } from '@multiformats/multiaddr';
5
+ import { peerIdFromString } from '@libp2p/peer-id';
6
+ const log = debug('sereus:cadre:seed-bootstrap');
7
+ /** Protocol ID for seed delivery */
8
+ export const SEED_PROTOCOL = '/sereus/seed/1.0.0';
9
+ /** Maximum seed message size (1MB) */
10
+ const MAX_SEED_SIZE = 1024 * 1024;
11
+ /**
12
+ * SeedBootstrapService handles control network seed generation and delivery.
13
+ *
14
+ * Seeds solve the cold-start problem: new nodes need control data to validate
15
+ * connections, but can't get data without connecting first. Seeds pre-populate
16
+ * the new node's cache with peer information and optionally transactions.
17
+ */
18
+ export class SeedBootstrapService {
19
+ constructor(config) {
20
+ this.libp2pNode = null;
21
+ this.controlDatabase = null;
22
+ this.eventCallbacks = {};
23
+ this.config = config;
24
+ // Derive public key from private key if not provided
25
+ if (config.authorityPrivateKey && !config.authorityPublicKey) {
26
+ this.authorityPublicKey = getPublicKey(config.authorityPrivateKey, 'ed25519', 'base64url', 'base64url');
27
+ }
28
+ else {
29
+ this.authorityPublicKey = config.authorityPublicKey ?? null;
30
+ }
31
+ log('SeedBootstrapService created for party: %s', config.partyId);
32
+ }
33
+ /**
34
+ * Set event callbacks for seed-related events.
35
+ * Used by CadreNode to emit events.
36
+ */
37
+ setEventCallbacks(callbacks) {
38
+ this.eventCallbacks = callbacks;
39
+ }
40
+ /**
41
+ * Initialize the service with libp2p node and control database
42
+ */
43
+ initialize(libp2pNode, controlDatabase) {
44
+ this.libp2pNode = libp2pNode;
45
+ this.controlDatabase = controlDatabase;
46
+ // Register the seed protocol handler
47
+ this.registerProtocolHandler();
48
+ log('SeedBootstrapService initialized');
49
+ }
50
+ /**
51
+ * Authorize a new peer to join the cadre.
52
+ * Signs the peer ID with the authority key and inserts into CadrePeer table.
53
+ */
54
+ async authorizePeer(options) {
55
+ const { peerId, multiaddrs } = options;
56
+ if (!this.config.authorityPrivateKey) {
57
+ throw new Error('Authority private key required to authorize peers');
58
+ }
59
+ if (!this.controlDatabase) {
60
+ throw new Error('Control database not initialized');
61
+ }
62
+ log('Authorizing peer: %s', peerId);
63
+ // Sign the peer ID with the authority key
64
+ const peerIdDigest = digest(peerId, 'sha256', 'utf8', 'base64url');
65
+ const signature = sign(peerIdDigest, this.config.authorityPrivateKey, 'ed25519', 'base64url', 'base64url', 'base64url');
66
+ // Insert into CadrePeer table with authority context
67
+ const db = this.controlDatabase.getDatabase();
68
+ const multiaddrStr = multiaddrs?.join(',') ?? null;
69
+ const multiaddrValue = multiaddrStr ? `'${multiaddrStr}'` : 'null';
70
+ await db.exec(`
71
+ insert into CadreControl.CadrePeer (PeerId, Multiaddr)
72
+ with context AuthorityKey = '${this.authorityPublicKey}', Signature = '${signature}'
73
+ values ('${peerId}', ${multiaddrValue})
74
+ `);
75
+ log('Peer %s authorized successfully', peerId);
76
+ }
77
+ /**
78
+ * Create a seed from the current control network state.
79
+ * The seed contains peer information and is signed by an authority.
80
+ */
81
+ async createSeed() {
82
+ if (!this.config.authorityPrivateKey || !this.authorityPublicKey) {
83
+ throw new Error('Authority key required to create seeds');
84
+ }
85
+ if (!this.controlDatabase || !this.libp2pNode) {
86
+ throw new Error('Service not initialized');
87
+ }
88
+ log('Creating seed for party: %s', this.config.partyId);
89
+ // Query all peers from the control database
90
+ const peers = await this.queryPeers();
91
+ // Create the seed data (without signature)
92
+ const seedData = {
93
+ partyId: this.config.partyId,
94
+ peers,
95
+ };
96
+ // Sign the seed
97
+ const seedJson = JSON.stringify(seedData);
98
+ const seedDigest = digest(seedJson, 'sha256', 'utf8', 'base64url');
99
+ const signature = sign(seedDigest, this.config.authorityPrivateKey, 'ed25519', 'base64url', 'base64url', 'base64url');
100
+ const seed = {
101
+ ...seedData,
102
+ signature,
103
+ signerKey: this.authorityPublicKey,
104
+ };
105
+ log('Created seed with %d peers', peers.length);
106
+ return seed;
107
+ }
108
+ /**
109
+ * Apply a seed to populate the peer cache and enable connections.
110
+ * Validates the seed signature before applying.
111
+ */
112
+ async applySeed(seed) {
113
+ if (!this.libp2pNode) {
114
+ return { success: false, peersAdded: 0, error: 'Service not initialized' };
115
+ }
116
+ log('Applying seed for party: %s', seed.partyId);
117
+ // Validate the seed signature
118
+ if (!this.validateSeedSignature(seed)) {
119
+ return { success: false, peersAdded: 0, error: 'Invalid seed signature' };
120
+ }
121
+ // Verify the signer is an authority in the seed's peer list
122
+ const signerPeer = seed.peers.find(p => p.isAuthority);
123
+ if (!signerPeer) {
124
+ return { success: false, peersAdded: 0, error: 'No authority peer in seed' };
125
+ }
126
+ let peersAdded = 0;
127
+ // Add peers to the peer store
128
+ for (const peer of seed.peers) {
129
+ try {
130
+ // Import peer multiaddrs into the peer store
131
+ if (peer.multiaddrs.length > 0) {
132
+ const peerId = peerIdFromString(peer.peerId);
133
+ const addrs = peer.multiaddrs.map(ma => multiaddr(ma));
134
+ await this.libp2pNode.peerStore.merge(peerId, {
135
+ multiaddrs: addrs
136
+ });
137
+ peersAdded++;
138
+ log('Added peer to store: %s with %d addrs', peer.peerId, addrs.length);
139
+ }
140
+ }
141
+ catch (error) {
142
+ log('Failed to add peer %s: %o', peer.peerId, error);
143
+ }
144
+ }
145
+ // Dial authority peers to establish connections
146
+ for (const peer of seed.peers.filter(p => p.isAuthority)) {
147
+ try {
148
+ if (peer.multiaddrs.length > 0) {
149
+ const addr = multiaddr(peer.multiaddrs[0]);
150
+ log('Dialing authority peer: %s', peer.peerId);
151
+ await this.libp2pNode.dial(addr);
152
+ }
153
+ }
154
+ catch (error) {
155
+ log('Failed to dial peer %s: %o', peer.peerId, error);
156
+ // Continue - not all peers need to be reachable
157
+ }
158
+ }
159
+ log('Applied seed: %d peers added', peersAdded);
160
+ return { success: true, peersAdded };
161
+ }
162
+ /**
163
+ * Encode a seed for out-of-band delivery (e.g., QR code, copy/paste).
164
+ */
165
+ encodeSeed(seed) {
166
+ const json = JSON.stringify(seed);
167
+ return uint8ArrayToString(new TextEncoder().encode(json), 'base64url');
168
+ }
169
+ /**
170
+ * Decode a seed from base64url encoding.
171
+ */
172
+ decodeSeed(encoded) {
173
+ const bytes = uint8ArrayFromString(encoded, 'base64url');
174
+ const json = new TextDecoder().decode(bytes);
175
+ return JSON.parse(json);
176
+ }
177
+ /**
178
+ * Deliver a seed directly to a peer via the /sereus/seed/1.0.0 protocol.
179
+ */
180
+ async deliverSeed(targetMultiaddr, seed) {
181
+ if (!this.libp2pNode) {
182
+ throw new Error('Service not initialized');
183
+ }
184
+ const addr = multiaddr(targetMultiaddr);
185
+ log('Delivering seed to: %s', targetMultiaddr);
186
+ // Dial the target and open a stream
187
+ const rawStream = await this.libp2pNode.dialProtocol(addr, SEED_PROTOCOL);
188
+ const stream = rawStream;
189
+ try {
190
+ // Send the seed message
191
+ const message = {
192
+ partyId: seed.partyId,
193
+ peers: seed.peers,
194
+ transactions: seed.transactions,
195
+ signature: seed.signature,
196
+ signerKey: seed.signerKey,
197
+ };
198
+ const messageBytes = new TextEncoder().encode(JSON.stringify(message));
199
+ // Write length-prefixed message
200
+ const lengthBytes = new Uint8Array(4);
201
+ new DataView(lengthBytes.buffer).setUint32(0, messageBytes.length, false);
202
+ async function* sinkData() { yield lengthBytes; yield messageBytes; }
203
+ await stream.sink(sinkData());
204
+ // Read the acknowledgment
205
+ const chunks = [];
206
+ for await (const chunk of stream.source) {
207
+ chunks.push(chunk.subarray());
208
+ // Read until we have the length prefix
209
+ if (chunks.reduce((sum, c) => sum + c.length, 0) >= 4)
210
+ break;
211
+ }
212
+ const responseData = new Uint8Array(chunks.reduce((sum, c) => sum + c.length, 0));
213
+ let offset = 0;
214
+ for (const chunk of chunks) {
215
+ responseData.set(chunk, offset);
216
+ offset += chunk.length;
217
+ }
218
+ // Parse length and read remaining data if needed
219
+ const responseLength = new DataView(responseData.buffer).getUint32(0, false);
220
+ const responseJson = new TextDecoder().decode(responseData.slice(4, 4 + responseLength));
221
+ const ack = JSON.parse(responseJson);
222
+ log('Seed delivery response: accepted=%s', ack.accepted);
223
+ return ack;
224
+ }
225
+ finally {
226
+ await stream.close();
227
+ }
228
+ }
229
+ /**
230
+ * Get this node's circuit relay address for inclusion in seeds.
231
+ * Returns null if no relay address is available.
232
+ */
233
+ async getRelayAddress() {
234
+ if (!this.libp2pNode) {
235
+ return null;
236
+ }
237
+ const addrs = this.libp2pNode.getMultiaddrs();
238
+ // Find a circuit relay address
239
+ const relayAddr = addrs.find(addr => addr.toString().includes('/p2p-circuit/'));
240
+ return relayAddr?.toString() ?? null;
241
+ }
242
+ /**
243
+ * Validate a seed's signature.
244
+ */
245
+ validateSeedSignature(seed) {
246
+ try {
247
+ // Reconstruct the signed data (seed without signature fields)
248
+ const seedData = {
249
+ partyId: seed.partyId,
250
+ peers: seed.peers,
251
+ ...(seed.transactions ? { transactions: seed.transactions } : {}),
252
+ };
253
+ const seedJson = JSON.stringify(seedData);
254
+ const seedDigest = digest(seedJson, 'sha256', 'utf8', 'base64url');
255
+ return verify(seedDigest, seed.signature, seed.signerKey, 'ed25519', 'base64url', 'base64url', 'base64url');
256
+ }
257
+ catch (error) {
258
+ log('Seed signature validation failed: %o', error);
259
+ return false;
260
+ }
261
+ }
262
+ /**
263
+ * Query peers from the control database.
264
+ */
265
+ async queryPeers() {
266
+ if (!this.controlDatabase) {
267
+ return [];
268
+ }
269
+ const db = this.controlDatabase.getDatabase();
270
+ const peers = [];
271
+ // First, get all authority keys
272
+ const authorityKeys = new Set();
273
+ for await (const row of db.eval('select Key from CadreControl.AuthorityKey')) {
274
+ authorityKeys.add(row.Key);
275
+ }
276
+ // Query CadrePeer table
277
+ for await (const row of db.eval('select PeerId, Multiaddr from CadreControl.CadrePeer')) {
278
+ const peerId = row.PeerId;
279
+ const multiaddr = row.Multiaddr;
280
+ // Check if this peer's public key is an authority
281
+ // Note: Authority keys are base64url public keys, not peer IDs
282
+ // For now, we mark the peer as authority if it matches the service's authority key
283
+ const isAuthority = peerId === this.libp2pNode?.peerId.toString();
284
+ peers.push({
285
+ peerId,
286
+ multiaddrs: multiaddr ? multiaddr.split(',') : [],
287
+ isAuthority,
288
+ });
289
+ }
290
+ return peers;
291
+ }
292
+ /**
293
+ * Register the seed protocol handler.
294
+ */
295
+ registerProtocolHandler() {
296
+ if (!this.libp2pNode)
297
+ return;
298
+ this.libp2pNode.handle(SEED_PROTOCOL, async (data) => {
299
+ const { stream, connection } = data;
300
+ const remotePeerId = connection.remotePeer.toString();
301
+ log('Incoming seed delivery from: %s', remotePeerId);
302
+ try {
303
+ // Read the seed message
304
+ const chunks = [];
305
+ let totalLength = 0;
306
+ for await (const chunk of stream.source) {
307
+ chunks.push(chunk.subarray());
308
+ totalLength += chunk.length;
309
+ if (totalLength > MAX_SEED_SIZE) {
310
+ throw new Error('Seed message too large');
311
+ }
312
+ }
313
+ const data = new Uint8Array(totalLength);
314
+ let offset = 0;
315
+ for (const chunk of chunks) {
316
+ data.set(chunk, offset);
317
+ offset += chunk.length;
318
+ }
319
+ // Parse length-prefixed message
320
+ const messageLength = new DataView(data.buffer).getUint32(0, false);
321
+ const messageJson = new TextDecoder().decode(data.slice(4, 4 + messageLength));
322
+ const message = JSON.parse(messageJson);
323
+ // Emit seed received event
324
+ this.eventCallbacks.onSeedReceived?.(message.partyId, remotePeerId);
325
+ // Convert to seed and apply
326
+ const seed = {
327
+ partyId: message.partyId,
328
+ peers: message.peers,
329
+ transactions: message.transactions,
330
+ signature: message.signature,
331
+ signerKey: message.signerKey,
332
+ };
333
+ const result = await this.applySeed(seed);
334
+ // Emit appropriate event based on result
335
+ if (result.success) {
336
+ this.eventCallbacks.onSeedApplied?.(seed.partyId, result.peersAdded);
337
+ }
338
+ else {
339
+ this.eventCallbacks.onSeedError?.(seed.partyId, result.error ?? 'Unknown error');
340
+ }
341
+ // Send acknowledgment
342
+ const ack = {
343
+ accepted: result.success,
344
+ reason: result.error,
345
+ };
346
+ const ackBytes = new TextEncoder().encode(JSON.stringify(ack));
347
+ const lengthBytes = new Uint8Array(4);
348
+ new DataView(lengthBytes.buffer).setUint32(0, ackBytes.length, false);
349
+ async function* sinkAck() { yield lengthBytes; yield ackBytes; }
350
+ await stream.sink(sinkAck());
351
+ }
352
+ catch (error) {
353
+ log('Error handling seed delivery: %o', error);
354
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
355
+ // Emit error event
356
+ this.eventCallbacks.onSeedError?.(this.config.partyId, errorMessage);
357
+ // Send error acknowledgment
358
+ const ack = {
359
+ accepted: false,
360
+ reason: errorMessage,
361
+ };
362
+ const ackBytes = new TextEncoder().encode(JSON.stringify(ack));
363
+ const lengthBytes = new Uint8Array(4);
364
+ new DataView(lengthBytes.buffer).setUint32(0, ackBytes.length, false);
365
+ try {
366
+ async function* sinkError() { yield lengthBytes; yield ackBytes; }
367
+ await stream.sink(sinkError());
368
+ }
369
+ catch {
370
+ // Ignore sink errors
371
+ }
372
+ }
373
+ finally {
374
+ await stream.close();
375
+ }
376
+ });
377
+ log('Registered seed protocol handler: %s', SEED_PROTOCOL);
378
+ }
379
+ /**
380
+ * Shutdown the service.
381
+ */
382
+ async shutdown() {
383
+ if (this.libp2pNode) {
384
+ await this.libp2pNode.unhandle(SEED_PROTOCOL);
385
+ }
386
+ this.libp2pNode = null;
387
+ this.controlDatabase = null;
388
+ log('SeedBootstrapService shutdown');
389
+ }
390
+ // ============================================================================
391
+ // Helper Functions for Common Scenarios
392
+ // ============================================================================
393
+ /**
394
+ * Add a drone to the cadre (phone/server adds provider-hosted node).
395
+ *
396
+ * Use this when you've spawned a drone via provider API and received its
397
+ * peer ID and multiaddrs. This method:
398
+ * 1. Authorizes the drone peer
399
+ * 2. Creates a seed including all current peers
400
+ * 3. Returns the seed for sending to provider API
401
+ *
402
+ * @param options - Drone peer info from provider API
403
+ * @returns Seed and encoded seed for drone initialization
404
+ */
405
+ async addDrone(options) {
406
+ const { dronePeerId, droneMultiaddrs } = options;
407
+ log('Adding drone: %s', dronePeerId);
408
+ // 1. Authorize the new drone peer
409
+ await this.authorizePeer({ peerId: dronePeerId, multiaddrs: droneMultiaddrs });
410
+ // 2. Create seed with current state
411
+ const seed = await this.createSeed();
412
+ // 3. Encode for transport
413
+ const encodedSeed = this.encodeSeed(seed);
414
+ log('Drone %s added, seed created with %d peers', dronePeerId, seed.peers.length);
415
+ return { seed, encodedSeed };
416
+ }
417
+ /**
418
+ * Create an invite for a phone to join the cadre.
419
+ *
420
+ * Use this when a server (public IP) wants to invite a phone (NAT'd).
421
+ * The invite is shared out-of-band (QR code, link, etc.) and contains
422
+ * the server's address so the phone can dial in.
423
+ *
424
+ * @param token - Optional invite token for validation
425
+ * @param expiresIn - Optional expiration time in milliseconds
426
+ * @returns Invite and encoded invite for sharing
427
+ */
428
+ async createInvite(token, expiresIn) {
429
+ if (!this.libp2pNode) {
430
+ throw new Error('Service not initialized');
431
+ }
432
+ log('Creating invite for phone');
433
+ // Get this node's dialable addresses
434
+ const addrs = this.libp2pNode.getMultiaddrs();
435
+ const authorityAddrs = addrs.map(a => a.toString());
436
+ const now = Date.now();
437
+ const invite = {
438
+ partyId: this.config.partyId,
439
+ authorityAddrs,
440
+ token,
441
+ createdAt: now,
442
+ expiresAt: expiresIn ? now + expiresIn : undefined,
443
+ };
444
+ const encodedInvite = this.encodeInvite(invite);
445
+ log('Invite created with %d authority addresses', authorityAddrs.length);
446
+ return { invite, encodedInvite };
447
+ }
448
+ /**
449
+ * Accept a phone connection using an invite.
450
+ *
451
+ * Use this when a phone dials in with an invite token. This method:
452
+ * 1. Validates the token if provided
453
+ * 2. Authorizes the phone peer
454
+ *
455
+ * After this, the phone can sync the control database normally.
456
+ *
457
+ * @param options - Phone peer info and invite token
458
+ * @param issuedInvite - The original invite for validation
459
+ */
460
+ async acceptPhone(options, issuedInvite) {
461
+ const { phonePeerId, token } = options;
462
+ log('Accepting phone: %s', phonePeerId);
463
+ // Validate token if invite provided
464
+ if (issuedInvite) {
465
+ if (issuedInvite.token && issuedInvite.token !== token) {
466
+ throw new Error('Invalid invite token');
467
+ }
468
+ if (issuedInvite.expiresAt && Date.now() > issuedInvite.expiresAt) {
469
+ throw new Error('Invite has expired');
470
+ }
471
+ }
472
+ // Authorize the phone peer (no multiaddrs - phone is NAT'd)
473
+ await this.authorizePeer({ peerId: phonePeerId });
474
+ log('Phone %s accepted and authorized', phonePeerId);
475
+ }
476
+ /**
477
+ * Add a phone to the cadre with relay support.
478
+ *
479
+ * Use this when both nodes are NAT'd (phone-to-phone). This method:
480
+ * 1. Authorizes the new phone peer
481
+ * 2. Creates a seed with relay addresses for dialing
482
+ *
483
+ * @param phonePeerId - Peer ID of the new phone
484
+ * @returns Seed with relay addresses for out-of-band delivery
485
+ */
486
+ async addPhoneWithRelay(phonePeerId) {
487
+ log('Adding phone with relay: %s', phonePeerId);
488
+ // 1. Authorize the new phone peer (no multiaddrs - NAT'd)
489
+ await this.authorizePeer({ peerId: phonePeerId });
490
+ // 2. Get relay address for this node
491
+ const relayAddr = await this.getRelayAddress();
492
+ // 3. Create seed - will include our relay address if available
493
+ const seed = await this.createSeed();
494
+ // If we have a relay address, make sure it's in our peer entry
495
+ if (relayAddr && this.libp2pNode) {
496
+ const ourPeerId = this.libp2pNode.peerId.toString();
497
+ const ourPeer = seed.peers.find(p => p.peerId === ourPeerId);
498
+ if (ourPeer && !ourPeer.multiaddrs.includes(relayAddr)) {
499
+ ourPeer.multiaddrs.push(relayAddr);
500
+ }
501
+ }
502
+ const encodedSeed = this.encodeSeed(seed);
503
+ log('Phone %s added with relay, seed created', phonePeerId);
504
+ return { seed, encodedSeed };
505
+ }
506
+ /**
507
+ * Encode an invite for out-of-band delivery.
508
+ */
509
+ encodeInvite(invite) {
510
+ const json = JSON.stringify(invite);
511
+ return uint8ArrayToString(new TextEncoder().encode(json), 'base64url');
512
+ }
513
+ /**
514
+ * Decode an invite from base64url encoding.
515
+ */
516
+ decodeInvite(encoded) {
517
+ const bytes = uint8ArrayFromString(encoded, 'base64url');
518
+ const json = new TextDecoder().decode(bytes);
519
+ return JSON.parse(json);
520
+ }
521
+ /**
522
+ * Dial an authority from an invite.
523
+ * Use this on a phone after receiving an invite to connect to the authority.
524
+ *
525
+ * @param invite - The invite received out-of-band
526
+ * @returns Connection to the authority
527
+ */
528
+ async dialInvite(invite) {
529
+ if (!this.libp2pNode) {
530
+ throw new Error('Service not initialized');
531
+ }
532
+ // Check expiration
533
+ if (invite.expiresAt && Date.now() > invite.expiresAt) {
534
+ throw new Error('Invite has expired');
535
+ }
536
+ log('Dialing invite authority with %d addresses', invite.authorityAddrs.length);
537
+ // Try each authority address until one succeeds
538
+ let lastError = null;
539
+ for (const addrStr of invite.authorityAddrs) {
540
+ try {
541
+ const addr = multiaddr(addrStr);
542
+ await this.libp2pNode.dial(addr);
543
+ log('Connected to authority at: %s', addrStr);
544
+ return;
545
+ }
546
+ catch (error) {
547
+ lastError = error instanceof Error ? error : new Error(String(error));
548
+ log('Failed to dial %s: %o', addrStr, error);
549
+ }
550
+ }
551
+ throw lastError ?? new Error('No authority addresses available');
552
+ }
553
+ }
554
+ //# sourceMappingURL=seed-bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-bootstrap.js","sourceRoot":"","sources":["../src/seed-bootstrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { Database } from '@quereus/quereus';
2
+ import type { Libp2p } from '@libp2p/interface';
3
+ import type { IRepo } from '@optimystic/db-core';
4
+ import type { SAppConfig } from './types.js';
5
+ export interface StrandDatabaseConfig {
6
+ /** The strand ID */
7
+ strandId: string;
8
+ /** sApp configuration containing the schema */
9
+ sAppConfig: SAppConfig;
10
+ /** Libp2p node for the strand network */
11
+ libp2pNode: Libp2p;
12
+ /** Coordinated repo from the libp2p node */
13
+ coordinatedRepo: IRepo;
14
+ }
15
+ /**
16
+ * StrandDatabase manages the sApp schema for a strand using Quereus with Optimystic backend.
17
+ * Each strand instance has its own isolated database with the sApp's schema applied.
18
+ */
19
+ export declare class StrandDatabase {
20
+ private db;
21
+ private collectionFactory;
22
+ private readonly config;
23
+ private initialized;
24
+ constructor(config: StrandDatabaseConfig);
25
+ /**
26
+ * Initialize the database - register plugins and execute sApp schema
27
+ */
28
+ initialize(): Promise<void>;
29
+ private executeSchema;
30
+ /**
31
+ * Get the underlying database for queries
32
+ */
33
+ getDatabase(): Database;
34
+ /**
35
+ * Close the database and cleanup resources
36
+ */
37
+ close(): Promise<void>;
38
+ private ensureInitialized;
39
+ }