peerbit 4.4.19-ad0f88c → 4.4.19-cb91e7b

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.
@@ -1,10 +1,11 @@
1
1
  import type { CircuitRelayService } from "@libp2p/circuit-relay-v2";
2
2
  import { DirectBlock } from "@peerbit/blocks";
3
3
  import { type IPeerbitKeychain } from "@peerbit/keychain";
4
- import { DirectSub } from "@peerbit/pubsub";
4
+ import { FanoutTree, TopicControlPlane } from "@peerbit/pubsub";
5
5
  import { type Libp2p, type Libp2pOptions, type ServiceFactoryMap } from "libp2p";
6
6
  export type Libp2pExtendServices = {
7
- pubsub: DirectSub;
7
+ pubsub: TopicControlPlane;
8
+ fanout: FanoutTree;
8
9
  blocks: DirectBlock;
9
10
  keychain: IPeerbitKeychain;
10
11
  };
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p.d.ts","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAEN,KAAK,gBAAgB,EAErB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACN,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEtB,MAAM,QAAQ,CAAC;AAGhB,MAAM,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,MAAM,CAClC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAAG,oBAAoB,CACpE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAC9C,OAAO,CAAC,oBAAoB,GAAG;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,CAAC,CAC7E,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,aAAa,CACrD,OAAO,CAAC,oBAAoB,GAAG;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,CAAC,CAC7E,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,mBAAmB,GAAG;IACnE,QAAQ,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAChC,OAAM,0BAML,KACC,OAAO,CAAC,cAAc,CAqDxB,CAAC"}
1
+ {"version":3,"file":"libp2p.d.ts","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EACN,KAAK,gBAAgB,EAErB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAyB,MAAM,iBAAiB,CAAC;AACvF,OAAO,EACN,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,iBAAiB,EAEtB,MAAM,QAAQ,CAAC;AAGhB,MAAM,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,MAAM,CAClC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAAG,oBAAoB,CACpE,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAC9C,OAAO,CAAC,oBAAoB,GAAG;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,CAAC,CAC7E,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,aAAa,CACrD,OAAO,CAAC,oBAAoB,GAAG;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,CAAC,CAC7E,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,mBAAmB,GAAG;IACnE,QAAQ,EAAE,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAChC,OAAM,0BAA+B,KACnC,OAAO,CAAC,cAAc,CAmExB,CAAC"}
@@ -2,18 +2,22 @@ import { noise } from "@chainsafe/libp2p-noise";
2
2
  import { yamux } from "@chainsafe/libp2p-yamux";
3
3
  import { identify } from "@libp2p/identify";
4
4
  import { DirectBlock } from "@peerbit/blocks";
5
- import { DefaultCryptoKeychain, keychain, } from "@peerbit/keychain";
6
- import { DirectSub } from "@peerbit/pubsub";
5
+ import { keychain, } from "@peerbit/keychain";
6
+ import { FanoutTree, TopicControlPlane, TopicRootControlPlane } from "@peerbit/pubsub";
7
7
  import { createLibp2p, } from "libp2p";
8
8
  import { listen, relay, transports } from "./transports.js";
9
- export const createLibp2pExtended = (opts = {
10
- services: {
11
- blocks: (c) => new DirectBlock(c),
12
- pubsub: (c) => new DirectSub(c),
13
- keychain: keychain(),
14
- },
15
- }) => {
9
+ export const createLibp2pExtended = (opts = {}) => {
10
+ const topicRootControlPlane = new TopicRootControlPlane();
16
11
  let extraServices = {};
12
+ let fanoutInstance;
13
+ const configuredFanoutFactory = opts.services?.fanout ||
14
+ ((c) => new FanoutTree(c, { connectionManager: false, topicRootControlPlane }));
15
+ const getOrCreateFanout = (c) => {
16
+ if (!fanoutInstance) {
17
+ fanoutInstance = configuredFanoutFactory(c);
18
+ }
19
+ return fanoutInstance;
20
+ };
17
21
  if (opts.services?.["relay"] === null) {
18
22
  delete opts.services?.["relay"];
19
23
  }
@@ -48,17 +52,20 @@ export const createLibp2pExtended = (opts = {
48
52
  connectionEncrypters: opts.connectionEncrypters || [noise()],
49
53
  streamMuxers: opts.streamMuxers || [yamux()],
50
54
  services: {
55
+ ...opts.services,
51
56
  pubsub: opts.services?.pubsub ||
52
- ((c) => new DirectSub(c, {
57
+ ((c) => new TopicControlPlane(c, {
53
58
  canRelayMessage: true,
59
+ topicRootControlPlane,
60
+ fanout: getOrCreateFanout(c),
54
61
  // auto dial true
55
62
  // auto prune true
56
63
  })),
64
+ fanout: (c) => getOrCreateFanout(c),
57
65
  blocks: opts.services?.blocks || ((c) => new DirectBlock(c)),
58
- keychain: opts.services?.keychain || ((c) => new DefaultCryptoKeychain()),
59
- ...opts.services,
66
+ keychain: opts.services?.keychain || keychain(),
60
67
  ...extraServices,
61
68
  },
62
- });
69
+ }).then((libp2p) => libp2p);
63
70
  };
64
71
  //# sourceMappingURL=libp2p.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p.js","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libp2p.js","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { type AnyStore } from "@peerbit/any-store";
4
4
  import { Ed25519Keypair, PublicSignKey } from "@peerbit/crypto";
5
5
  import type { Indices } from "@peerbit/indexer-interface";
6
6
  import { type Address, type ExtractArgs, type OpenOptions, type Program, type ProgramClient, ProgramHandler } from "@peerbit/program";
7
+ import { FanoutChannel, type FanoutTreeChannelOptions, type FanoutTreeJoinOptions } from "@peerbit/pubsub";
7
8
  import { type Libp2pExtended, type PartialLibp2pCreateOptions } from "./libp2p.js";
8
9
  export declare const logger: import("@libp2p/interface").Logger;
9
10
  export type OptionalCreateOptions = {
@@ -49,7 +50,10 @@ export declare class Peerbit implements ProgramClient {
49
50
  /**
50
51
  * Dial a peer with an Ed25519 peerId
51
52
  */
52
- dial(address: string | Multiaddr | Multiaddr[] | ProgramClient): Promise<boolean>;
53
+ dial(address: string | Multiaddr | Multiaddr[] | ProgramClient, options?: {
54
+ dialTimeoutMs?: number;
55
+ signal?: AbortSignal;
56
+ }): Promise<boolean>;
53
57
  hangUp(address: PeerId | PublicSignKey | string | Multiaddr): Promise<void>;
54
58
  start(): Promise<void>;
55
59
  stop(): Promise<void>;
@@ -62,6 +66,11 @@ export declare class Peerbit implements ProgramClient {
62
66
  * @returns
63
67
  */
64
68
  open<S extends Program<ExtractArgs<S>>>(storeOrAddress: S | Address | string, options?: OpenOptions<S>): Promise<S>;
69
+ fanoutChannel(topic: string, root?: string): FanoutChannel;
70
+ fanoutResolveRoot(topic: string): Promise<string>;
71
+ fanoutOpenAsRoot(topic: string, options: Omit<FanoutTreeChannelOptions, "role">): import("@peerbit/pubsub").FanoutTreeChannelId;
72
+ fanoutJoin(topic: string, root: string, options: Omit<FanoutTreeChannelOptions, "role">, joinOpts?: FanoutTreeJoinOptions): Promise<void>;
73
+ fanoutJoinAuto(topic: string, options: Omit<FanoutTreeChannelOptions, "role">, joinOpts?: FanoutTreeJoinOptions): Promise<void>;
65
74
  get storage(): AnyStore;
66
75
  get indexer(): Indices;
67
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../../src/peer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../../src/peer.ts"],"names":[],"mappings":"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"}
package/dist/src/peer.js CHANGED
@@ -3,12 +3,11 @@ import { keys } from "@libp2p/crypto";
3
3
  import { isMultiaddr, multiaddr, } from "@multiformats/multiaddr";
4
4
  import { createStore } from "@peerbit/any-store";
5
5
  import { DirectBlock } from "@peerbit/blocks";
6
- import { Ed25519Keypair, Ed25519PublicKey, PublicSignKey, Secp256k1Keypair, getKeypairFromPrivateKey, } from "@peerbit/crypto";
7
- import { create as createSQLiteIndexer } from "@peerbit/indexer-sqlite3";
6
+ import { Ed25519Keypair, Ed25519PublicKey, PublicSignKey, Secp256k1Keypair, getPublicKeyFromPeerId, getKeypairFromPrivateKey, } from "@peerbit/crypto";
8
7
  import { DefaultCryptoKeychain, keychain } from "@peerbit/keychain";
9
8
  import { logger as loggerFn } from "@peerbit/logger";
10
9
  import { ProgramHandler, } from "@peerbit/program";
11
- import { DirectSub } from "@peerbit/pubsub";
10
+ import { FanoutChannel, FanoutTree, TopicControlPlane, TopicRootControlPlane, } from "@peerbit/pubsub";
12
11
  import sodium from "libsodium-wrappers";
13
12
  import path from "path-browserify";
14
13
  import { concat } from "uint8arrays";
@@ -64,7 +63,12 @@ export class Peerbit {
64
63
  const directory = options.directory;
65
64
  const hasDir = directory != null;
66
65
  const storage = await createCache(directory != null ? path.join(directory, "/cache") : undefined);
67
- const indexerFn = options.indexer || createSQLiteIndexer;
66
+ const indexerFn = options.indexer ||
67
+ (async (directory) => {
68
+ // Lazy-import to avoid loading sqlite-wasm in browser-like runtimes/tests
69
+ const { create } = await import("@peerbit/indexer-sqlite3");
70
+ return create(directory);
71
+ });
68
72
  const indexer = directory != null
69
73
  ? await indexerFn(path.join(directory, "/index"))
70
74
  : await indexerFn();
@@ -103,13 +107,109 @@ export class Peerbit {
103
107
  ]))
104
108
  : undefined;
105
109
  }
110
+ const topicRootControlPlane = new TopicRootControlPlane();
111
+ // Keep a single FanoutTree instance per peer so pubsub sharding + provider
112
+ // discovery share the same overlay.
113
+ let fanoutInstance;
114
+ const configuredFanoutFactory = extendedOptions?.services?.fanout ||
115
+ ((c) => new FanoutTree(c, {
116
+ connectionManager: false,
117
+ topicRootControlPlane,
118
+ }));
119
+ const getOrCreateFanout = (c) => {
120
+ if (!fanoutInstance) {
121
+ fanoutInstance = configuredFanoutFactory(c);
122
+ }
123
+ return fanoutInstance;
124
+ };
125
+ const blockProviderNamespace = (cid) => `cid:${cid}`;
106
126
  const services = {
107
127
  keychain: (components) => keychain({ libp2p: {}, crypto: cryptoKeychain })(components),
108
- blocks: (c) => new DirectBlock(c, {
128
+ fanout: (c) => getOrCreateFanout(c),
129
+ blocks: (c) => {
130
+ let blocksService;
131
+ const fanout = (() => {
132
+ try {
133
+ return getOrCreateFanout(c);
134
+ }
135
+ catch {
136
+ return undefined;
137
+ }
138
+ })();
139
+ const fallbackConnectedPeers = () => {
140
+ const out = [];
141
+ const push = (hash) => {
142
+ if (!hash)
143
+ return;
144
+ if (hash === blocksService?.publicKeyHash)
145
+ return;
146
+ // Small bounded list; avoid Set allocations on hot paths.
147
+ if (out.includes(hash))
148
+ return;
149
+ out.push(hash);
150
+ };
151
+ // Prefer peers we've already negotiated `/peerbit/direct-block` streams with.
152
+ for (const h of blocksService?.peers.keys() ?? []) {
153
+ push(h);
154
+ if (out.length >= 32)
155
+ return out;
156
+ }
157
+ // Fall back to currently connected libp2p peers.
158
+ for (const conn of c.connectionManager.getConnections()) {
159
+ try {
160
+ push(getPublicKeyFromPeerId(conn.remotePeer).hashcode());
161
+ }
162
+ catch {
163
+ // ignore unexpected key types
164
+ }
165
+ if (out.length >= 32)
166
+ break;
167
+ }
168
+ return out;
169
+ };
170
+ const resolveProviders = async (cid, options) => {
171
+ // 1) tracker-backed provider directory (best-effort, bounded)
172
+ try {
173
+ const providers = await fanout?.queryProviders(blockProviderNamespace(cid), {
174
+ want: 8,
175
+ timeoutMs: 2_000,
176
+ queryTimeoutMs: 500,
177
+ bootstrapMaxPeers: 2,
178
+ signal: options?.signal,
179
+ });
180
+ if (providers && providers.length > 0)
181
+ return providers;
182
+ }
183
+ catch {
184
+ // ignore discovery failures
185
+ }
186
+ // 2) fallback to currently connected peers (keeps local/small nets working without trackers)
187
+ return fallbackConnectedPeers();
188
+ };
189
+ blocksService = new DirectBlock(c, {
190
+ canRelayMessage: asRelay,
191
+ directory: blocksDirectory,
192
+ resolveProviders,
193
+ onPut: async (cid) => {
194
+ // Best-effort directory announce for "get without remote.from" workflows.
195
+ try {
196
+ await fanout?.announceProvider(blockProviderNamespace(cid), {
197
+ ttlMs: 120_000,
198
+ bootstrapMaxPeers: 2,
199
+ });
200
+ }
201
+ catch {
202
+ // ignore announce failures
203
+ }
204
+ },
205
+ });
206
+ return blocksService;
207
+ },
208
+ pubsub: (c) => new TopicControlPlane(c, {
109
209
  canRelayMessage: asRelay,
110
- directory: blocksDirectory,
210
+ topicRootControlPlane,
211
+ fanout: getOrCreateFanout(c),
111
212
  }),
112
- pubsub: (c) => new DirectSub(c, { canRelayMessage: asRelay }),
113
213
  ...extendedOptions?.services,
114
214
  };
115
215
  if (!asRelay) {
@@ -188,32 +288,67 @@ export class Peerbit {
188
288
  /**
189
289
  * Dial a peer with an Ed25519 peerId
190
290
  */
191
- async dial(address) {
291
+ async dial(address, options) {
192
292
  const maddress = typeof address === "string"
193
293
  ? multiaddr(address)
194
294
  : isMultiaddr(address) || Array.isArray(address)
195
295
  ? address
196
296
  : address.getMultiaddrs();
197
- const connection = await this.libp2p.dial(maddress);
198
- const publicKey = Ed25519PublicKey.fromPeerId(connection.remotePeer);
199
- // TODO, do this as a promise instead using the onPeerConnected vents in pubsub and blocks
200
- try {
201
- await this.libp2p.services.pubsub.waitFor(publicKey.hashcode(), {
202
- target: "neighbor",
203
- });
204
- }
205
- catch (error) {
206
- throw new Error(`Failed to dial peer. Not available on Pubsub`);
297
+ let dialSignal = options?.signal;
298
+ let dialAbortController;
299
+ let dialTimeout;
300
+ let onAbort;
301
+ if (options?.dialTimeoutMs != null) {
302
+ dialAbortController = new AbortController();
303
+ const abort = (reason) => {
304
+ if (dialAbortController?.signal.aborted)
305
+ return;
306
+ dialAbortController?.abort(reason);
307
+ };
308
+ dialTimeout = setTimeout(() => {
309
+ abort(new Error(`Dial timeout after ${options.dialTimeoutMs}ms`));
310
+ }, options.dialTimeoutMs);
311
+ if (dialSignal) {
312
+ if (dialSignal.aborted) {
313
+ abort(dialSignal.reason);
314
+ }
315
+ else {
316
+ onAbort = () => abort(dialSignal?.reason);
317
+ dialSignal.addEventListener("abort", onAbort, { once: true });
318
+ }
319
+ }
320
+ dialSignal = dialAbortController.signal;
207
321
  }
208
322
  try {
209
- await this.libp2p.services.blocks.waitFor(publicKey.hashcode(), {
210
- target: "neighbor",
211
- });
323
+ const connection = await this.libp2p.dial(maddress, dialSignal ? { signal: dialSignal } : undefined);
324
+ const publicKey = Ed25519PublicKey.fromPeerId(connection.remotePeer);
325
+ const peerHash = publicKey.hashcode();
326
+ // TODO, do this as a promise instead using the onPeerConnected vents in pubsub and blocks
327
+ try {
328
+ await this.libp2p.services.pubsub.waitFor(peerHash, {
329
+ target: "neighbor",
330
+ });
331
+ }
332
+ catch (error) {
333
+ throw new Error(`Failed to dial peer. Not available on Pubsub`);
334
+ }
335
+ try {
336
+ await this.libp2p.services.blocks.waitFor(peerHash, {
337
+ target: "neighbor",
338
+ });
339
+ }
340
+ catch (error) {
341
+ throw new Error(`Failed to dial peer. Not available on Blocks`);
342
+ }
343
+ return true;
212
344
  }
213
- catch (error) {
214
- throw new Error(`Failed to dial peer. Not available on Blocks`);
345
+ finally {
346
+ if (dialTimeout)
347
+ clearTimeout(dialTimeout);
348
+ if (onAbort && options?.signal) {
349
+ options.signal.removeEventListener("abort", onAbort);
350
+ }
215
351
  }
216
- return true;
217
352
  }
218
353
  async hangUp(address) {
219
354
  await this.libp2p.hangUp(address instanceof PublicSignKey
@@ -246,7 +381,73 @@ export class Peerbit {
246
381
  if (_addresses.length === 0) {
247
382
  throw new Error("Failed to find any addresses to dial");
248
383
  }
249
- const settled = await Promise.allSettled(_addresses.map((x) => this.dial(x)));
384
+ const extractPeerId = (a) => {
385
+ const s = typeof a === "string" ? a : a.toString();
386
+ const m = s.match(/\/(?:p2p|ipfs)\/([^/]+)(?:\/|$)/);
387
+ return m?.[1];
388
+ };
389
+ // Keep fanout bootstrap config aligned with peer bootstrap config so fanout
390
+ // channels can join via the same rendezvous nodes.
391
+ try {
392
+ this.libp2p.services.fanout.setBootstraps(_addresses);
393
+ }
394
+ catch {
395
+ // ignore if fanout service is not present/overridden
396
+ }
397
+ // Avoid dialing the same peer multiple times concurrently (multiaddrs often come
398
+ // with both `/tcp` and `/ws` addresses for the same peer). Concurrent dials to
399
+ // the same peer can race internal stream readiness, causing waits to stall.
400
+ const byPeerId = new Map();
401
+ const unknown = [];
402
+ for (const a of _addresses) {
403
+ const pid = extractPeerId(a);
404
+ if (!pid) {
405
+ unknown.push(a);
406
+ continue;
407
+ }
408
+ const list = byPeerId.get(pid) ?? [];
409
+ list.push(a);
410
+ byPeerId.set(pid, list);
411
+ }
412
+ const dialTimeoutMs = 30_000;
413
+ const scoreBootstrapAddr = (a) => {
414
+ const s = a.toString();
415
+ const isCircuit = s.includes("p2p-circuit");
416
+ const isWs = s.includes("/ws") || s.includes("/wss");
417
+ return (isCircuit ? 2 : 0) + (isWs ? 1 : 0);
418
+ };
419
+ const dialPeer = async (list) => {
420
+ const maddrs = list
421
+ .map((x) => (typeof x === "string" ? multiaddr(x) : x))
422
+ .sort((a, b) => scoreBootstrapAddr(a) - scoreBootstrapAddr(b));
423
+ let lastError;
424
+ for (const ma of maddrs) {
425
+ try {
426
+ await this.dial(ma, { dialTimeoutMs });
427
+ return true;
428
+ }
429
+ catch (e) {
430
+ lastError = e;
431
+ }
432
+ }
433
+ throw lastError ?? new Error("Failed to dial bootstrap peer");
434
+ };
435
+ const dialTasks = [];
436
+ for (const list of byPeerId.values()) {
437
+ dialTasks.push({
438
+ label: list.map((x) => (typeof x === "string" ? x : x.toString())),
439
+ promise: dialPeer(list),
440
+ });
441
+ }
442
+ for (const a of unknown) {
443
+ dialTasks.push({
444
+ label: [typeof a === "string" ? a : a.toString()],
445
+ promise: this.dial(typeof a === "string" ? multiaddr(a) : a, {
446
+ dialTimeoutMs,
447
+ }),
448
+ });
449
+ }
450
+ const settled = await Promise.allSettled(dialTasks.map((t) => t.promise));
250
451
  let once = false;
251
452
  for (const [i, result] of settled.entries()) {
252
453
  if (result.status === "fulfilled") {
@@ -254,7 +455,7 @@ export class Peerbit {
254
455
  }
255
456
  else {
256
457
  logger.error("Failed to dial bootstrap address(s): " +
257
- JSON.stringify(_addresses[i]) +
458
+ JSON.stringify(dialTasks[i]?.label ?? []) +
258
459
  ". Reason: " +
259
460
  result.reason);
260
461
  }
@@ -262,6 +463,76 @@ export class Peerbit {
262
463
  if (!once) {
263
464
  throw new Error("Failed to succefully dial any bootstrap node");
264
465
  }
466
+ // Seed deterministic topic-root candidates for shard root resolution.
467
+ //
468
+ // IMPORTANT: this set must be stable across peers, otherwise different nodes
469
+ // will resolve different roots for the same shard and the overlay will partition.
470
+ //
471
+ // We therefore constrain candidates to the bootstrap peerIds we were asked
472
+ // to dial (and that we successfully connected to).
473
+ const servicesAny = this.libp2p.services;
474
+ const fanoutPlane = servicesAny?.fanout?.topicRootControlPlane;
475
+ const pubsubPlane = servicesAny?.pubsub?.topicRootControlPlane;
476
+ const planes = [...new Set([fanoutPlane, pubsubPlane].filter(Boolean))];
477
+ if (planes.length > 0) {
478
+ const bootstrapPeerIds = new Set();
479
+ for (const a of _addresses) {
480
+ const pid = extractPeerId(a);
481
+ if (pid)
482
+ bootstrapPeerIds.add(pid);
483
+ }
484
+ const candidates = new Set();
485
+ for (const connection of this.libp2p.getConnections()) {
486
+ if (bootstrapPeerIds.size > 0) {
487
+ const remoteId = connection.remotePeer?.toString?.();
488
+ if (!remoteId || !bootstrapPeerIds.has(remoteId))
489
+ continue;
490
+ }
491
+ try {
492
+ candidates.add(getPublicKeyFromPeerId(connection.remotePeer).hashcode());
493
+ }
494
+ catch {
495
+ // ignore peers without a resolvable public key
496
+ }
497
+ }
498
+ // If this node is itself one of the bootstraps, it won't show up among
499
+ // remote connections; add it explicitly so shard mapping matches other peers.
500
+ try {
501
+ if (bootstrapPeerIds.has(this.libp2p.peerId.toString())) {
502
+ candidates.add(this.services.pubsub.publicKeyHash);
503
+ }
504
+ }
505
+ catch {
506
+ // ignore
507
+ }
508
+ if (candidates.size > 0) {
509
+ const list = [...candidates];
510
+ // Prefer the pubsub helper so we also disable its auto-candidate mode.
511
+ try {
512
+ this.services.pubsub?.setTopicRootCandidates?.(list);
513
+ }
514
+ catch {
515
+ // ignore
516
+ }
517
+ for (const plane of planes) {
518
+ try {
519
+ plane.setTopicRootCandidates(list);
520
+ }
521
+ catch {
522
+ // ignore
523
+ }
524
+ }
525
+ // Open shard roots this node is responsible for (no-op for non-candidates).
526
+ try {
527
+ if (list.includes(this.services.pubsub.publicKeyHash)) {
528
+ await this.services.pubsub.hostShardRootsNow();
529
+ }
530
+ }
531
+ catch {
532
+ // ignore
533
+ }
534
+ }
535
+ }
265
536
  }
266
537
  /**
267
538
  * Default behaviour of a store is only to accept heads that are forks (new roots) with some probability
@@ -273,6 +544,32 @@ export class Peerbit {
273
544
  async open(storeOrAddress, options = {}) {
274
545
  return (this._handler || (this._handler = new ProgramHandler({ client: this }))).open(storeOrAddress, options);
275
546
  }
547
+ fanoutChannel(topic, root = this.services.fanout.publicKeyHash) {
548
+ if (root === this.services.fanout.publicKeyHash) {
549
+ return FanoutChannel.fromSelf(this.services.fanout, topic);
550
+ }
551
+ return new FanoutChannel(this.services.fanout, { topic, root });
552
+ }
553
+ async fanoutResolveRoot(topic) {
554
+ const servicesAny = this.services;
555
+ const topicRootControlPlane = servicesAny?.fanout?.topicRootControlPlane ||
556
+ servicesAny?.pubsub?.topicRootControlPlane;
557
+ const resolved = await topicRootControlPlane?.resolveTopicRoot?.(topic);
558
+ if (!resolved) {
559
+ throw new Error(`Failed to resolve fanout root for topic ${topic}. Configure topic-root candidates/resolver (Peerbit.bootstrap() does this automatically) or pass root explicitly.`);
560
+ }
561
+ return resolved;
562
+ }
563
+ fanoutOpenAsRoot(topic, options) {
564
+ return this.fanoutChannel(topic).openAsRoot(options);
565
+ }
566
+ fanoutJoin(topic, root, options, joinOpts) {
567
+ return this.fanoutChannel(topic, root).join(options, joinOpts);
568
+ }
569
+ async fanoutJoinAuto(topic, options, joinOpts) {
570
+ const root = await this.fanoutResolveRoot(topic);
571
+ return this.fanoutJoin(topic, root, options, joinOpts);
572
+ }
276
573
  get storage() {
277
574
  return this._storage;
278
575
  }
@@ -1 +1 @@
1
- {"version":3,"file":"peer.js","sourceRoot":"","sources":["../../src/peer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../../src/peer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peerbit",
3
- "version": "4.4.19-ad0f88c",
3
+ "version": "4.4.19-cb91e7b",
4
4
  "description": "Peerbit client",
5
5
  "author": "dao.xyz",
6
6
  "license": "MIT",
@@ -73,16 +73,16 @@
73
73
  "@libp2p/webrtc": "^6.0.3",
74
74
  "@libp2p/websockets": "^10.1.0",
75
75
  "@multiformats/multiaddr": "^13.0.1",
76
- "@peerbit/any-store": "2.2.4-ad0f88c",
77
- "@peerbit/any-store-opfs": "1.1.3-ad0f88c",
78
- "@peerbit/crypto": "2.4.1-ad0f88c",
79
- "@peerbit/indexer-interface": "2.1.1-ad0f88c",
80
- "@peerbit/logger": "2.0.0-ad0f88c",
81
- "@peerbit/time": "2.3.0-ad0f88c",
82
- "@peerbit/build-assets": "1.1.0-ad0f88c",
83
- "@peerbit/keychain": "1.2.4-ad0f88c",
84
- "@peerbit/indexer-simple": "1.2.2-ad0f88c",
85
- "@peerbit/indexer-sqlite3": "2.1.2-ad0f88c",
76
+ "@peerbit/any-store": "2.2.4-cb91e7b",
77
+ "@peerbit/any-store-opfs": "1.1.3-cb91e7b",
78
+ "@peerbit/crypto": "2.4.1-cb91e7b",
79
+ "@peerbit/indexer-interface": "2.1.1-cb91e7b",
80
+ "@peerbit/logger": "2.0.0-cb91e7b",
81
+ "@peerbit/time": "2.3.0-cb91e7b",
82
+ "@peerbit/build-assets": "1.1.0-cb91e7b",
83
+ "@peerbit/keychain": "1.2.4-cb91e7b",
84
+ "@peerbit/indexer-simple": "1.2.2-cb91e7b",
85
+ "@peerbit/indexer-sqlite3": "2.1.2-cb91e7b",
86
86
  "@sqlite.org/sqlite-wasm": "^3.51.1-build1",
87
87
  "@dao-xyz/datastore-level": "^11.2.0",
88
88
  "@chainsafe/libp2p-yamux": "^8.0.0",
@@ -92,10 +92,10 @@
92
92
  "libp2p": "^3.1.0",
93
93
  "p-queue": "^8.0.1",
94
94
  "uint8arrays": "^5.1.0",
95
- "@peerbit/program": "5.6.3-ad0f88c",
96
- "@peerbit/blocks": "3.1.8-ad0f88c",
97
- "@peerbit/pubsub": "4.1.4-ad0f88c",
98
- "@peerbit/stream-interface": "5.4.0-ad0f88c",
95
+ "@peerbit/program": "5.6.3-cb91e7b",
96
+ "@peerbit/blocks": "3.1.8-cb91e7b",
97
+ "@peerbit/pubsub": "4.1.4-cb91e7b",
98
+ "@peerbit/stream-interface": "5.4.0-cb91e7b",
99
99
  "libsodium-wrappers": "0.7.15"
100
100
  },
101
101
  "devDependencies": {
package/src/libp2p.ts CHANGED
@@ -4,11 +4,10 @@ import type { CircuitRelayService } from "@libp2p/circuit-relay-v2";
4
4
  import { identify } from "@libp2p/identify";
5
5
  import { DirectBlock } from "@peerbit/blocks";
6
6
  import {
7
- DefaultCryptoKeychain,
8
7
  type IPeerbitKeychain,
9
8
  keychain,
10
9
  } from "@peerbit/keychain";
11
- import { DirectSub } from "@peerbit/pubsub";
10
+ import { FanoutTree, TopicControlPlane, TopicRootControlPlane } from "@peerbit/pubsub";
12
11
  import {
13
12
  type Libp2p,
14
13
  type Libp2pOptions,
@@ -18,7 +17,8 @@ import {
18
17
  import { listen, relay, transports } from "./transports.js";
19
18
 
20
19
  export type Libp2pExtendServices = {
21
- pubsub: DirectSub;
20
+ pubsub: TopicControlPlane;
21
+ fanout: FanoutTree;
22
22
  blocks: DirectBlock;
23
23
  keychain: IPeerbitKeychain;
24
24
  };
@@ -39,15 +39,20 @@ export type Libp2pCreateOptionsWithServices = Libp2pCreateOptions & {
39
39
  };
40
40
 
41
41
  export const createLibp2pExtended = (
42
- opts: PartialLibp2pCreateOptions = {
43
- services: {
44
- blocks: (c: any) => new DirectBlock(c),
45
- pubsub: (c: any) => new DirectSub(c),
46
- keychain: keychain(),
47
- },
48
- },
42
+ opts: PartialLibp2pCreateOptions = {},
49
43
  ): Promise<Libp2pExtended> => {
44
+ const topicRootControlPlane = new TopicRootControlPlane();
50
45
  let extraServices: any = {};
46
+ let fanoutInstance: FanoutTree | undefined;
47
+ const configuredFanoutFactory =
48
+ opts.services?.fanout ||
49
+ ((c) => new FanoutTree(c, { connectionManager: false, topicRootControlPlane }));
50
+ const getOrCreateFanout = (c: any) => {
51
+ if (!fanoutInstance) {
52
+ fanoutInstance = configuredFanoutFactory(c) as FanoutTree;
53
+ }
54
+ return fanoutInstance;
55
+ };
51
56
 
52
57
  if (opts.services?.["relay"] === null) {
53
58
  delete opts.services?.["relay"];
@@ -85,18 +90,21 @@ export const createLibp2pExtended = (
85
90
  connectionEncrypters: opts.connectionEncrypters || [noise()],
86
91
  streamMuxers: opts.streamMuxers || [yamux()],
87
92
  services: {
93
+ ...opts.services,
88
94
  pubsub:
89
95
  opts.services?.pubsub ||
90
96
  ((c) =>
91
- new DirectSub(c, {
97
+ new TopicControlPlane(c, {
92
98
  canRelayMessage: true,
99
+ topicRootControlPlane,
100
+ fanout: getOrCreateFanout(c),
93
101
  // auto dial true
94
102
  // auto prune true
95
103
  })),
104
+ fanout: (c) => getOrCreateFanout(c),
96
105
  blocks: opts.services?.blocks || ((c) => new DirectBlock(c)),
97
- keychain: opts.services?.keychain || ((c) => new DefaultCryptoKeychain()),
98
- ...opts.services,
106
+ keychain: opts.services?.keychain || keychain(),
99
107
  ...extraServices,
100
108
  },
101
- });
109
+ }).then((libp2p) => libp2p as Libp2pExtended);
102
110
  };
package/src/peer.ts CHANGED
@@ -14,10 +14,10 @@ import {
14
14
  Ed25519PublicKey,
15
15
  PublicSignKey,
16
16
  Secp256k1Keypair,
17
+ getPublicKeyFromPeerId,
17
18
  getKeypairFromPrivateKey,
18
19
  } from "@peerbit/crypto";
19
20
  import type { Indices } from "@peerbit/indexer-interface";
20
- import { create as createSQLiteIndexer } from "@peerbit/indexer-sqlite3";
21
21
  import { DefaultCryptoKeychain, keychain } from "@peerbit/keychain";
22
22
  import { logger as loggerFn } from "@peerbit/logger";
23
23
  import {
@@ -28,7 +28,14 @@ import {
28
28
  type ProgramClient,
29
29
  ProgramHandler,
30
30
  } from "@peerbit/program";
31
- import { DirectSub } from "@peerbit/pubsub";
31
+ import {
32
+ FanoutChannel,
33
+ FanoutTree,
34
+ TopicControlPlane,
35
+ TopicRootControlPlane,
36
+ type FanoutTreeChannelOptions,
37
+ type FanoutTreeJoinOptions,
38
+ } from "@peerbit/pubsub";
32
39
  import type { Libp2p } from "libp2p";
33
40
  import sodium from "libsodium-wrappers";
34
41
  import path from "path-browserify";
@@ -132,7 +139,13 @@ export class Peerbit implements ProgramClient {
132
139
  const storage = await createCache(
133
140
  directory != null ? path.join(directory, "/cache") : undefined,
134
141
  );
135
- const indexerFn = options.indexer || createSQLiteIndexer;
142
+ const indexerFn =
143
+ options.indexer ||
144
+ (async (directory?: string) => {
145
+ // Lazy-import to avoid loading sqlite-wasm in browser-like runtimes/tests
146
+ const { create } = await import("@peerbit/indexer-sqlite3");
147
+ return create(directory);
148
+ });
136
149
  const indexer =
137
150
  directory != null
138
151
  ? await indexerFn(path.join(directory, "/index"))
@@ -186,19 +199,123 @@ export class Peerbit implements ProgramClient {
186
199
  ]),
187
200
  )
188
201
  : undefined;
189
- }
190
-
191
- const services: any = {
192
- keychain: (components: KeychainComponents) =>
193
- keychain({ libp2p: {}, crypto: cryptoKeychain })(components),
194
- blocks: (c: any) =>
195
- new DirectBlock(c, {
196
- canRelayMessage: asRelay,
197
- directory: blocksDirectory,
198
- }),
199
- pubsub: (c: any) => new DirectSub(c, { canRelayMessage: asRelay }),
200
- ...extendedOptions?.services,
201
- };
202
+ }
203
+
204
+ const topicRootControlPlane = new TopicRootControlPlane();
205
+
206
+ // Keep a single FanoutTree instance per peer so pubsub sharding + provider
207
+ // discovery share the same overlay.
208
+ let fanoutInstance: FanoutTree | undefined;
209
+ const configuredFanoutFactory =
210
+ extendedOptions?.services?.fanout ||
211
+ ((c: any) =>
212
+ new FanoutTree(c, {
213
+ connectionManager: false,
214
+ topicRootControlPlane,
215
+ }));
216
+ const getOrCreateFanout = (c: any) => {
217
+ if (!fanoutInstance) {
218
+ fanoutInstance = configuredFanoutFactory(c) as FanoutTree;
219
+ }
220
+ return fanoutInstance;
221
+ };
222
+
223
+ const blockProviderNamespace = (cid: string) => `cid:${cid}`;
224
+
225
+ const services: any = {
226
+ keychain: (components: KeychainComponents) =>
227
+ keychain({ libp2p: {}, crypto: cryptoKeychain })(components),
228
+ fanout: (c: any) => getOrCreateFanout(c),
229
+ blocks: (c: any) => {
230
+ let blocksService: DirectBlock | undefined;
231
+ const fanout = (() => {
232
+ try {
233
+ return getOrCreateFanout(c);
234
+ } catch {
235
+ return undefined;
236
+ }
237
+ })();
238
+
239
+ const fallbackConnectedPeers = () => {
240
+ const out: string[] = [];
241
+ const push = (hash?: string) => {
242
+ if (!hash) return;
243
+ if (hash === blocksService?.publicKeyHash) return;
244
+ // Small bounded list; avoid Set allocations on hot paths.
245
+ if (out.includes(hash)) return;
246
+ out.push(hash);
247
+ };
248
+
249
+ // Prefer peers we've already negotiated `/peerbit/direct-block` streams with.
250
+ for (const h of blocksService?.peers.keys() ?? []) {
251
+ push(h);
252
+ if (out.length >= 32) return out;
253
+ }
254
+
255
+ // Fall back to currently connected libp2p peers.
256
+ for (const conn of c.connectionManager.getConnections()) {
257
+ try {
258
+ push(getPublicKeyFromPeerId(conn.remotePeer).hashcode());
259
+ } catch {
260
+ // ignore unexpected key types
261
+ }
262
+ if (out.length >= 32) break;
263
+ }
264
+
265
+ return out;
266
+ };
267
+
268
+ const resolveProviders = async (
269
+ cid: string,
270
+ options?: { signal?: AbortSignal },
271
+ ) => {
272
+ // 1) tracker-backed provider directory (best-effort, bounded)
273
+ try {
274
+ const providers = await fanout?.queryProviders(
275
+ blockProviderNamespace(cid),
276
+ {
277
+ want: 8,
278
+ timeoutMs: 2_000,
279
+ queryTimeoutMs: 500,
280
+ bootstrapMaxPeers: 2,
281
+ signal: options?.signal,
282
+ },
283
+ );
284
+ if (providers && providers.length > 0) return providers;
285
+ } catch {
286
+ // ignore discovery failures
287
+ }
288
+
289
+ // 2) fallback to currently connected peers (keeps local/small nets working without trackers)
290
+ return fallbackConnectedPeers();
291
+ };
292
+
293
+ blocksService = new DirectBlock(c, {
294
+ canRelayMessage: asRelay,
295
+ directory: blocksDirectory,
296
+ resolveProviders,
297
+ onPut: async (cid) => {
298
+ // Best-effort directory announce for "get without remote.from" workflows.
299
+ try {
300
+ await fanout?.announceProvider(blockProviderNamespace(cid), {
301
+ ttlMs: 120_000,
302
+ bootstrapMaxPeers: 2,
303
+ });
304
+ } catch {
305
+ // ignore announce failures
306
+ }
307
+ },
308
+ });
309
+ return blocksService;
310
+ },
311
+ pubsub: (c: any) =>
312
+ new TopicControlPlane(c, {
313
+ canRelayMessage: asRelay,
314
+ topicRootControlPlane,
315
+ fanout: getOrCreateFanout(c),
316
+ }),
317
+ ...extendedOptions?.services,
318
+ };
202
319
 
203
320
  if (!asRelay) {
204
321
  services.relay = null;
@@ -294,6 +411,7 @@ export class Peerbit implements ProgramClient {
294
411
  */
295
412
  async dial(
296
413
  address: string | Multiaddr | Multiaddr[] | ProgramClient,
414
+ options?: { dialTimeoutMs?: number; signal?: AbortSignal },
297
415
  ): Promise<boolean> {
298
416
  const maddress =
299
417
  typeof address === "string"
@@ -301,27 +419,68 @@ export class Peerbit implements ProgramClient {
301
419
  : isMultiaddr(address) || Array.isArray(address)
302
420
  ? address
303
421
  : address.getMultiaddrs();
304
- const connection = await this.libp2p.dial(maddress);
305
422
 
306
- const publicKey = Ed25519PublicKey.fromPeerId(connection.remotePeer);
423
+ let dialSignal: AbortSignal | undefined = options?.signal;
424
+ let dialAbortController: AbortController | undefined;
425
+ let dialTimeout: ReturnType<typeof setTimeout> | undefined;
426
+ let onAbort: (() => void) | undefined;
307
427
 
308
- // TODO, do this as a promise instead using the onPeerConnected vents in pubsub and blocks
309
- try {
310
- await this.libp2p.services.pubsub.waitFor(publicKey.hashcode(), {
311
- target: "neighbor",
312
- });
313
- } catch (error) {
314
- throw new Error(`Failed to dial peer. Not available on Pubsub`);
428
+ if (options?.dialTimeoutMs != null) {
429
+ dialAbortController = new AbortController();
430
+ const abort = (reason?: unknown) => {
431
+ if (dialAbortController?.signal.aborted) return;
432
+ dialAbortController?.abort(reason);
433
+ };
434
+
435
+ dialTimeout = setTimeout(() => {
436
+ abort(new Error(`Dial timeout after ${options.dialTimeoutMs}ms`));
437
+ }, options.dialTimeoutMs);
438
+
439
+ if (dialSignal) {
440
+ if (dialSignal.aborted) {
441
+ abort(dialSignal.reason);
442
+ } else {
443
+ onAbort = () => abort(dialSignal?.reason);
444
+ dialSignal.addEventListener("abort", onAbort, { once: true });
445
+ }
446
+ }
447
+
448
+ dialSignal = dialAbortController.signal;
315
449
  }
316
450
 
317
451
  try {
318
- await this.libp2p.services.blocks.waitFor(publicKey.hashcode(), {
319
- target: "neighbor",
320
- });
321
- } catch (error) {
322
- throw new Error(`Failed to dial peer. Not available on Blocks`);
452
+ const connection = await this.libp2p.dial(
453
+ maddress as any,
454
+ dialSignal ? ({ signal: dialSignal } as any) : undefined,
455
+ );
456
+
457
+ const publicKey = Ed25519PublicKey.fromPeerId(connection.remotePeer);
458
+ const peerHash = publicKey.hashcode();
459
+
460
+ // TODO, do this as a promise instead using the onPeerConnected vents in pubsub and blocks
461
+ try {
462
+ await this.libp2p.services.pubsub.waitFor(peerHash, {
463
+ target: "neighbor",
464
+ });
465
+ } catch (error) {
466
+ throw new Error(`Failed to dial peer. Not available on Pubsub`);
467
+ }
468
+
469
+ try {
470
+ await this.libp2p.services.blocks.waitFor(peerHash, {
471
+ target: "neighbor",
472
+ });
473
+ } catch (error) {
474
+ throw new Error(`Failed to dial peer. Not available on Blocks`);
475
+ }
476
+
477
+ return true;
478
+ } finally {
479
+ if (dialTimeout) clearTimeout(dialTimeout);
480
+ if (onAbort && options?.signal) {
481
+ options.signal.removeEventListener("abort", onAbort);
482
+ }
323
483
  }
324
- return true;
325
484
  }
326
485
 
327
486
  async hangUp(address: PeerId | PublicSignKey | string | Multiaddr) {
@@ -361,9 +520,78 @@ export class Peerbit implements ProgramClient {
361
520
  if (_addresses.length === 0) {
362
521
  throw new Error("Failed to find any addresses to dial");
363
522
  }
364
- const settled = await Promise.allSettled(
365
- _addresses.map((x) => this.dial(x)),
366
- );
523
+
524
+ const extractPeerId = (a: string | Multiaddr): string | undefined => {
525
+ const s = typeof a === "string" ? a : a.toString();
526
+ const m = s.match(/\/(?:p2p|ipfs)\/([^/]+)(?:\/|$)/);
527
+ return m?.[1];
528
+ };
529
+
530
+ // Keep fanout bootstrap config aligned with peer bootstrap config so fanout
531
+ // channels can join via the same rendezvous nodes.
532
+ try {
533
+ this.libp2p.services.fanout.setBootstraps(_addresses);
534
+ } catch {
535
+ // ignore if fanout service is not present/overridden
536
+ }
537
+
538
+ // Avoid dialing the same peer multiple times concurrently (multiaddrs often come
539
+ // with both `/tcp` and `/ws` addresses for the same peer). Concurrent dials to
540
+ // the same peer can race internal stream readiness, causing waits to stall.
541
+ const byPeerId = new Map<string, (string | Multiaddr)[]>();
542
+ const unknown: (string | Multiaddr)[] = [];
543
+ for (const a of _addresses) {
544
+ const pid = extractPeerId(a as any);
545
+ if (!pid) {
546
+ unknown.push(a);
547
+ continue;
548
+ }
549
+ const list = byPeerId.get(pid) ?? [];
550
+ list.push(a);
551
+ byPeerId.set(pid, list);
552
+ }
553
+
554
+ const dialTimeoutMs = 30_000;
555
+ const scoreBootstrapAddr = (a: Multiaddr) => {
556
+ const s = a.toString();
557
+ const isCircuit = s.includes("p2p-circuit");
558
+ const isWs = s.includes("/ws") || s.includes("/wss");
559
+ return (isCircuit ? 2 : 0) + (isWs ? 1 : 0);
560
+ };
561
+
562
+ const dialPeer = async (list: (string | Multiaddr)[]) => {
563
+ const maddrs = list
564
+ .map((x) => (typeof x === "string" ? multiaddr(x) : x))
565
+ .sort((a, b) => scoreBootstrapAddr(a) - scoreBootstrapAddr(b));
566
+ let lastError: unknown;
567
+ for (const ma of maddrs) {
568
+ try {
569
+ await this.dial(ma, { dialTimeoutMs });
570
+ return true;
571
+ } catch (e) {
572
+ lastError = e;
573
+ }
574
+ }
575
+ throw lastError ?? new Error("Failed to dial bootstrap peer");
576
+ };
577
+
578
+ const dialTasks: Array<{ label: string[]; promise: Promise<boolean> }> = [];
579
+ for (const list of byPeerId.values()) {
580
+ dialTasks.push({
581
+ label: list.map((x) => (typeof x === "string" ? x : x.toString())),
582
+ promise: dialPeer(list),
583
+ });
584
+ }
585
+ for (const a of unknown) {
586
+ dialTasks.push({
587
+ label: [typeof a === "string" ? a : a.toString()],
588
+ promise: this.dial(typeof a === "string" ? multiaddr(a) : a, {
589
+ dialTimeoutMs,
590
+ }),
591
+ });
592
+ }
593
+
594
+ const settled = await Promise.allSettled(dialTasks.map((t) => t.promise));
367
595
  let once = false;
368
596
  for (const [i, result] of settled.entries()) {
369
597
  if (result.status === "fulfilled") {
@@ -371,7 +599,7 @@ export class Peerbit implements ProgramClient {
371
599
  } else {
372
600
  logger.error(
373
601
  "Failed to dial bootstrap address(s): " +
374
- JSON.stringify(_addresses[i]) +
602
+ JSON.stringify(dialTasks[i]?.label ?? []) +
375
603
  ". Reason: " +
376
604
  result.reason,
377
605
  );
@@ -380,6 +608,71 @@ export class Peerbit implements ProgramClient {
380
608
  if (!once) {
381
609
  throw new Error("Failed to succefully dial any bootstrap node");
382
610
  }
611
+
612
+ // Seed deterministic topic-root candidates for shard root resolution.
613
+ //
614
+ // IMPORTANT: this set must be stable across peers, otherwise different nodes
615
+ // will resolve different roots for the same shard and the overlay will partition.
616
+ //
617
+ // We therefore constrain candidates to the bootstrap peerIds we were asked
618
+ // to dial (and that we successfully connected to).
619
+ const servicesAny: any = this.libp2p.services as any;
620
+ const fanoutPlane = servicesAny?.fanout?.topicRootControlPlane;
621
+ const pubsubPlane = servicesAny?.pubsub?.topicRootControlPlane;
622
+ const planes = [...new Set([fanoutPlane, pubsubPlane].filter(Boolean))];
623
+ if (planes.length > 0) {
624
+ const bootstrapPeerIds = new Set<string>();
625
+ for (const a of _addresses) {
626
+ const pid = extractPeerId(a as any);
627
+ if (pid) bootstrapPeerIds.add(pid);
628
+ }
629
+
630
+ const candidates = new Set<string>();
631
+ for (const connection of this.libp2p.getConnections()) {
632
+ if (bootstrapPeerIds.size > 0) {
633
+ const remoteId = connection.remotePeer?.toString?.();
634
+ if (!remoteId || !bootstrapPeerIds.has(remoteId)) continue;
635
+ }
636
+ try {
637
+ candidates.add(getPublicKeyFromPeerId(connection.remotePeer).hashcode());
638
+ } catch {
639
+ // ignore peers without a resolvable public key
640
+ }
641
+ }
642
+ // If this node is itself one of the bootstraps, it won't show up among
643
+ // remote connections; add it explicitly so shard mapping matches other peers.
644
+ try {
645
+ if (bootstrapPeerIds.has(this.libp2p.peerId.toString())) {
646
+ candidates.add(this.services.pubsub.publicKeyHash);
647
+ }
648
+ } catch {
649
+ // ignore
650
+ }
651
+ if (candidates.size > 0) {
652
+ const list = [...candidates];
653
+ // Prefer the pubsub helper so we also disable its auto-candidate mode.
654
+ try {
655
+ (this.services.pubsub as any)?.setTopicRootCandidates?.(list);
656
+ } catch {
657
+ // ignore
658
+ }
659
+ for (const plane of planes) {
660
+ try {
661
+ plane.setTopicRootCandidates(list);
662
+ } catch {
663
+ // ignore
664
+ }
665
+ }
666
+ // Open shard roots this node is responsible for (no-op for non-candidates).
667
+ try {
668
+ if (list.includes(this.services.pubsub.publicKeyHash)) {
669
+ await this.services.pubsub.hostShardRootsNow();
670
+ }
671
+ } catch {
672
+ // ignore
673
+ }
674
+ }
675
+ }
383
676
  }
384
677
 
385
678
  /**
@@ -399,6 +692,52 @@ export class Peerbit implements ProgramClient {
399
692
  ).open(storeOrAddress, options);
400
693
  }
401
694
 
695
+ public fanoutChannel(topic: string, root: string = this.services.fanout.publicKeyHash) {
696
+ if (root === this.services.fanout.publicKeyHash) {
697
+ return FanoutChannel.fromSelf(this.services.fanout, topic);
698
+ }
699
+ return new FanoutChannel(this.services.fanout, { topic, root });
700
+ }
701
+
702
+ public async fanoutResolveRoot(topic: string): Promise<string> {
703
+ const servicesAny: any = this.services as any;
704
+ const topicRootControlPlane =
705
+ servicesAny?.fanout?.topicRootControlPlane ||
706
+ servicesAny?.pubsub?.topicRootControlPlane;
707
+ const resolved = await topicRootControlPlane?.resolveTopicRoot?.(topic);
708
+ if (!resolved) {
709
+ throw new Error(
710
+ `Failed to resolve fanout root for topic ${topic}. Configure topic-root candidates/resolver (Peerbit.bootstrap() does this automatically) or pass root explicitly.`,
711
+ );
712
+ }
713
+ return resolved;
714
+ }
715
+
716
+ public fanoutOpenAsRoot(
717
+ topic: string,
718
+ options: Omit<FanoutTreeChannelOptions, "role">,
719
+ ) {
720
+ return this.fanoutChannel(topic).openAsRoot(options);
721
+ }
722
+
723
+ public fanoutJoin(
724
+ topic: string,
725
+ root: string,
726
+ options: Omit<FanoutTreeChannelOptions, "role">,
727
+ joinOpts?: FanoutTreeJoinOptions,
728
+ ) {
729
+ return this.fanoutChannel(topic, root).join(options, joinOpts);
730
+ }
731
+
732
+ public async fanoutJoinAuto(
733
+ topic: string,
734
+ options: Omit<FanoutTreeChannelOptions, "role">,
735
+ joinOpts?: FanoutTreeJoinOptions,
736
+ ) {
737
+ const root = await this.fanoutResolveRoot(topic);
738
+ return this.fanoutJoin(topic, root, options, joinOpts);
739
+ }
740
+
402
741
  get storage() {
403
742
  return this._storage;
404
743
  }