@le-space/aleph-bootstrap 0.9.3 → 0.9.4

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.
package/README.md CHANGED
@@ -12,6 +12,8 @@ It is designed for two complementary jobs:
12
12
 
13
13
  - `discoverAlephBootstrapMultiaddrs(options)`
14
14
  - `createLibp2pAlephBootstrap(options)`
15
+ - `filterRelayBootstrapPostsByProfile(posts, profile?)`
16
+ - `filterRelayBootstrapPostsByRegistration(posts, registrationId?)`
15
17
  - `filterPublicMultiaddrs(addrs, options?)`
16
18
  - `createRelayBootstrapPost(options)`
17
19
  - `signRelayBootstrapAuthorization(args)`
@@ -45,6 +47,34 @@ By default, discovery will:
45
47
  - verify dual-key records when they are present
46
48
  - ignore malformed or invalid dual-key records
47
49
 
50
+ ## Scoping discovery
51
+
52
+ The channel is shared. Several relay implementations register in it, and so
53
+ does every throwaway relay an E2E run starts — under the same profile as the
54
+ production one, with a registration that outlives the machine it describes,
55
+ because guests self-publish with generated keys and no remaining key can
56
+ FORGET the post.
57
+
58
+ Two scopes, and most consumers want both:
59
+
60
+ ```ts
61
+ const list = await discoverAlephBootstrapMultiaddrs({
62
+ profile: 'orbitdb-relay', // not uc-go-peer's relays
63
+ registrationId: 'relay:orbitdb-relay:orbitdb-relay' // and not the E2E ones
64
+ })
65
+ ```
66
+
67
+ `profile` keeps out relays a consumer cannot use at all — an orbitdb app that
68
+ dials a `uc-go-peer` relay never gets a shared circuit and sits at
69
+ `candidates: 0`. `registrationId` keeps out its own corpses: measured
70
+ downstream, a browser probe wave against an unscoped list spent its outbound
71
+ stream budget on dead addresses and wrote off the one healthy relay along with
72
+ them.
73
+
74
+ Use `registrationId` for anything that bakes addresses into a build or dials
75
+ them on start. Omit both to see the whole channel, which is what a dashboard
76
+ wants.
77
+
48
78
  If a consumer wants to require the stronger model:
49
79
 
50
80
  ```ts
package/index.d.ts CHANGED
@@ -103,6 +103,15 @@ interface DiscoverAlephBootstrapOptions {
103
103
  * When omitted, posts of every profile are returned (previous behaviour).
104
104
  */
105
105
  profile?: string | readonly string[];
106
+ /**
107
+ * Restrict discovery further, to the registrations published under this id
108
+ * (e.g. `"relay:orbitdb-relay:orbitdb-relay"`). Profile is not fine enough:
109
+ * an E2E run's throwaway relays register under the same profile as the
110
+ * production one, and a registration outlives the machine it describes. Use
111
+ * this for anything that bakes addresses into a build or dials them on
112
+ * start; omit it to see the whole channel.
113
+ */
114
+ registrationId?: string | readonly string[];
106
115
  fetch?: typeof fetch;
107
116
  }
108
117
  interface FilterPublicMultiaddrsOptions {
@@ -219,10 +228,30 @@ declare function selectCurrentRelayBootstrapPosts(posts: readonly RelayBootstrap
219
228
  * A missing/empty filter is a no-op so existing callers are unaffected.
220
229
  */
221
230
  declare function filterRelayBootstrapPostsByProfile(posts: readonly RelayBootstrapPostRecord[], profile?: string | readonly string[]): RelayBootstrapPostRecord[];
231
+ /**
232
+ * Keep only the registrations a consumer published for itself.
233
+ *
234
+ * Profile is not fine enough. Every ephemeral relay an E2E run starts
235
+ * registers under the same profile as the production one - as
236
+ * `relay:<profile>:<name>-e2e-*` - and a registration outlives the machine it
237
+ * describes, because guests self-publish with generated keys and no remaining
238
+ * key can FORGET the post. So the channel accumulates registrations that are
239
+ * indistinguishable from the real one by profile alone, and were alive when
240
+ * they were written.
241
+ *
242
+ * Measured downstream: a browser probe wave against that list exhausted its
243
+ * outbound stream budget on dead addresses and wrote off the one healthy relay
244
+ * along with the corpses, leaving both browsers with nothing to dial.
245
+ *
246
+ * Omitting the scope returns every registration, which is the previous
247
+ * behaviour and the right default for a consumer that wants to see the channel
248
+ * rather than its own corner of it.
249
+ */
250
+ declare function filterRelayBootstrapPostsByRegistration(posts: readonly RelayBootstrapPostRecord[], registrationId?: string | readonly string[]): RelayBootstrapPostRecord[];
222
251
  declare function discoverAlephBootstrapMultiaddrs(options?: DiscoverAlephBootstrapOptions): Promise<string[]>;
223
252
  declare function createLibp2pAlephBootstrap(options?: DiscoverAlephBootstrapOptions & {
224
253
  timeout?: number;
225
254
  tagName?: string;
226
255
  }): Promise<ReturnType<typeof bootstrap>>;
227
256
 
228
- export { type CreateRelayBootstrapPostOptions, DEFAULT_ALEPH_API_HOST, DEFAULT_ALEPH_BOOTSTRAP_CHANNEL, DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE, DEFAULT_ALEPH_BOOTSTRAP_REF, DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT, DEFAULT_BOOTSTRAP_MAX_AGE_MS, DEFAULT_BOOTSTRAP_MAX_PAGES, DEFAULT_BOOTSTRAP_PAGINATION, type DiscoverAlephBootstrapOptions, type FilterPublicMultiaddrsOptions, RELAY_BOOTSTRAP_SIGNATURE_SCHEME, type RelayBootstrapAuthorizationPayload, type RelayBootstrapAuthorizationRecord, type RelayBootstrapContent, type RelayBootstrapPostContent, type RelayBootstrapPostRecord, type RelayBootstrapProofPayload, type RelayBootstrapProofRecord, type RelayBootstrapProofSigner, type RelayBootstrapTrustMode, type RelayBootstrapVerificationResult, buildRelayBootstrapPostContent, createLibp2pAlephBootstrap, createRelayBootstrapPost, dedupeMultiaddrs, discoverAlephBootstrapMultiaddrs, fetchAlephBootstrapPosts, filterPublicMultiaddrs, filterRelayBootstrapPostsByProfile, isBrowserDialableMultiaddr, isPublicMultiaddr, relayBootstrapMultiaddrsHash, relayBootstrapTrustMode, selectCompactRelayBootstrapMultiaddrs, selectCurrentRelayBootstrapPosts, signRelayBootstrapAuthorization, signRelayBootstrapProof, verifyRelayBootstrapAuthorization, verifyRelayBootstrapDualKeyContent, verifyRelayBootstrapProof };
257
+ export { type CreateRelayBootstrapPostOptions, DEFAULT_ALEPH_API_HOST, DEFAULT_ALEPH_BOOTSTRAP_CHANNEL, DEFAULT_ALEPH_BOOTSTRAP_POST_TYPE, DEFAULT_ALEPH_BOOTSTRAP_REF, DEFAULT_BOOTSTRAP_COMPACT_MULTIADDR_LIMIT, DEFAULT_BOOTSTRAP_MAX_AGE_MS, DEFAULT_BOOTSTRAP_MAX_PAGES, DEFAULT_BOOTSTRAP_PAGINATION, type DiscoverAlephBootstrapOptions, type FilterPublicMultiaddrsOptions, RELAY_BOOTSTRAP_SIGNATURE_SCHEME, type RelayBootstrapAuthorizationPayload, type RelayBootstrapAuthorizationRecord, type RelayBootstrapContent, type RelayBootstrapPostContent, type RelayBootstrapPostRecord, type RelayBootstrapProofPayload, type RelayBootstrapProofRecord, type RelayBootstrapProofSigner, type RelayBootstrapTrustMode, type RelayBootstrapVerificationResult, buildRelayBootstrapPostContent, createLibp2pAlephBootstrap, createRelayBootstrapPost, dedupeMultiaddrs, discoverAlephBootstrapMultiaddrs, fetchAlephBootstrapPosts, filterPublicMultiaddrs, filterRelayBootstrapPostsByProfile, filterRelayBootstrapPostsByRegistration, isBrowserDialableMultiaddr, isPublicMultiaddr, relayBootstrapMultiaddrsHash, relayBootstrapTrustMode, selectCompactRelayBootstrapMultiaddrs, selectCurrentRelayBootstrapPosts, signRelayBootstrapAuthorization, signRelayBootstrapProof, verifyRelayBootstrapAuthorization, verifyRelayBootstrapDualKeyContent, verifyRelayBootstrapProof };
package/index.js CHANGED
@@ -653,6 +653,14 @@ function filterRelayBootstrapPostsByProfile(posts, profile) {
653
653
  (post) => post.content != null && allowed.has(String(post.content.profile))
654
654
  );
655
655
  }
656
+ function filterRelayBootstrapPostsByRegistration(posts, registrationId) {
657
+ const wanted = (typeof registrationId === "string" ? [registrationId] : registrationId ?? []).map((entry) => entry.trim()).filter(Boolean);
658
+ if (wanted.length === 0) return [...posts];
659
+ const allowed = new Set(wanted);
660
+ return posts.filter(
661
+ (post) => post.content != null && allowed.has(String(post.content.registrationId))
662
+ );
663
+ }
656
664
  async function filterTrustedRelayBootstrapPosts(posts, options = {}) {
657
665
  const requireDualKeyAttestation = options.requireDualKeyAttestation ?? false;
658
666
  const verifyDualKeyAttestation = options.verifyDualKeyAttestation ?? true;
@@ -692,11 +700,14 @@ async function discoverAlephBootstrapMultiaddrs(options = {}) {
692
700
  pagination
693
701
  });
694
702
  collectedPosts.push(...pagePosts);
695
- const selectedPosts = filterRelayBootstrapPostsByProfile(
696
- selectCurrentRelayBootstrapPosts(collectedPosts, {
697
- maxAgeMs: options.maxAgeMs
698
- }),
699
- options.profile
703
+ const selectedPosts = filterRelayBootstrapPostsByRegistration(
704
+ filterRelayBootstrapPostsByProfile(
705
+ selectCurrentRelayBootstrapPosts(collectedPosts, {
706
+ maxAgeMs: options.maxAgeMs
707
+ }),
708
+ options.profile
709
+ ),
710
+ options.registrationId
700
711
  );
701
712
  const trustedPosts = await filterTrustedRelayBootstrapPosts(selectedPosts, {
702
713
  requireDualKeyAttestation: options.requireDualKeyAttestation,
@@ -757,6 +768,7 @@ export {
757
768
  fetchAlephBootstrapPosts,
758
769
  filterPublicMultiaddrs,
759
770
  filterRelayBootstrapPostsByProfile,
771
+ filterRelayBootstrapPostsByRegistration,
760
772
  isBrowserDialableMultiaddr,
761
773
  isPublicMultiaddr,
762
774
  relayBootstrapMultiaddrsHash,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@le-space/aleph-bootstrap",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "description": "Aleph-backed libp2p bootstrap discovery and relay registration helpers.",
5
5
  "license": "MIT",
6
6
  "type": "module",