Initial Commit
This commit is contained in:
153
packages/networking/network/network-discovery-gundb/README.md
Normal file
153
packages/networking/network/network-discovery-gundb/README.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# @suaveplan/network-discovery-gundb - Browser-tier GunDB DiscoveryStrategy: gossip-over-WebSocket peer discovery via Gun. Relay list REQUIRED — no public-relay fallback. Mandatory Ed25519-signed peer announces. Zod wire-payload validation. Constant-time peer-ID compare. AbortSignal + EventBusLike + ServiceRegistry + OTel + Zod boundaries.
|
||||
|
||||
## Summary
|
||||
|
||||
Browser-tier `DiscoveryStrategy` for `@suaveplan/network-bootstrap`
|
||||
chains. Wraps a [GunDB](https://gun.eco) instance — gossip-over-
|
||||
WebSocket decentralised graph database — and exposes a deduped, capped
|
||||
peer set to the bootstrap pipeline.
|
||||
|
||||
GunDB is flagged security-fragile upstream; this release tightens
|
||||
every relevant attack surface.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [gundb-discovery](./src/core/gundb-discovery/gundb-discovery.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [gundb-discovery](./src/core/gundb-discovery/gundb-discovery.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [envelope-signing](./src/transport/envelope-signing.md) — Provides the cryptographic helpers used by `GunDBTransport` to sign every outgoing `MessageEnvelope` and verify every i…
|
||||
- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||||
<!-- end:auto-docs --> - [gundb-discovery](./src/core/gundb-discovery/gundb-discovery.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [envelope-signing](./src/transport/envelope-signing.md) — Provides the cryptographic helpers used by `GunDBTransport` to sign every outgoing `MessageEnvelope` and verify every i…
|
||||
- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [gundb-discovery](./src/core/gundb-discovery/gundb-discovery.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [envelope-signing](./src/transport/envelope-signing.md) — Provides the cryptographic helpers used by `GunDBTransport` to sign every outgoing `MessageEnvelope` and verify every i…
|
||||
- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [gundb-discovery](./src/core/gundb-discovery/gundb-discovery.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [envelope-signing](./src/transport/envelope-signing.md) — Provides the cryptographic helpers used by `GunDBTransport` to sign every outgoing `MessageEnvelope` and verify every i…
|
||||
- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_- [gundb-discovery](./src/core/gundb-discovery/gundb-discovery.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_ - [errors](./src/errors/errors.md) — <!-- begin:auto-docs --> _(no submodules)_- [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_ - [otel](./src/otel/otel.md) — <!-- begin:auto-docs --> _(no submodules)_- [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_ - [plugin](./src/plugin/plugin.md) — <!-- begin:auto-docs --> _(no submodules)_- [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_ - [signing](./src/signing/signing.md) — <!-- begin:auto-docs --> _(no submodules)_- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_ - [envelope-signing](./src/transport/envelope-signing.md) — Provides the cryptographic helpers used by `GunDBTransport` to sign every outgoing `MessageEnvelope` and verify every i…
|
||||
- [transport](./src/transport/transport.md) — <!-- begin:auto-docs --> _(no submodules)_- [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_ - [types](./src/types/types.md) — <!-- begin:auto-docs --> _(no submodules)_
|
||||
## Why this package
|
||||
|
||||
- Plug-and-play `DiscoveryStrategy` slot for network bootstrap
|
||||
chains. Works alongside `@suaveplan/network-discovery-peerjs`,
|
||||
`@suaveplan/network-discovery-trystero`,
|
||||
`@suaveplan/network-discovery-webtorrent`, and
|
||||
`@suaveplan/network-discovery-crdt`.
|
||||
- **Relay list REQUIRED.** Upstream's public-relay fallback
|
||||
(`https://gun-manhattan.herokuapp.com/gun`) is removed. Callers must
|
||||
supply their own relays.
|
||||
- **Every outbound announce is Ed25519-signed.** The local peer's
|
||||
32-byte secret is the contract input.
|
||||
- **Every inbound announce is Zod-parsed AND Ed25519-verified before
|
||||
admission.** Failures silently drop the payload and increment
|
||||
`gundb.invalid_messages_total{reason}` /
|
||||
`gundb.signature_rejected_total{reason}` — a malicious peer cannot
|
||||
crash a node by gossiping garbage.
|
||||
- **Constant-time peer-ID compare** via `constantTimeEqual` from
|
||||
`@suaveplan/crypto-utils`.
|
||||
- Injectable `gunFactory` — production wires the real `Gun(config)`;
|
||||
tests bind a deterministic `GunNodeLike` fake (no `vi.mock` ever
|
||||
used).
|
||||
- Typed `EventBusLike<GunDBEventMap>` integration.
|
||||
- Optional `@suaveplan/service-discovery` `ServiceRegistry` mirroring.
|
||||
- OTel surface: `disc_gundb.start` span; counters
|
||||
`peers_discovered_total{outcome}`,
|
||||
`gundb.invalid_messages_total{reason}`,
|
||||
`gundb.signature_rejected_total{reason}`,
|
||||
`disc_gundb.relay_errors_total{relay}`; histogram
|
||||
`gundb_announce_duration_ms`.
|
||||
- `AbortSignal` honoured on every async public method.
|
||||
- 100% test + branch + function + line coverage.
|
||||
|
||||
## Basic example
|
||||
|
||||
```ts
|
||||
import { GunDBDiscovery, publicKeyHex } from "@suaveplan/network-discovery-gundb";
|
||||
|
||||
const signingKey = crypto.getRandomValues(new Uint8Array(32));
|
||||
const localPeerId = publicKeyHex(signingKey);
|
||||
|
||||
const discovery = new GunDBDiscovery({
|
||||
peers: ["wss://my-private-relay.example.com/gun"],
|
||||
gunFactory: async (cfg) => {
|
||||
const { default: Gun } = await import("gun");
|
||||
return Gun({ peers: cfg.peers as string[] }) as unknown as GunNodeLike;
|
||||
},
|
||||
localPeerId,
|
||||
signingKey,
|
||||
});
|
||||
|
||||
await discovery.start();
|
||||
const peers = await discovery.discover(5_000);
|
||||
console.log(`found ${peers.length} peers`);
|
||||
await discovery.stop();
|
||||
```
|
||||
|
||||
## Advanced example
|
||||
|
||||
```ts
|
||||
import { EventBus } from "@suaveplan/events";
|
||||
import { ServiceRegistry } from "@suaveplan/service-discovery";
|
||||
import { DiscoveryChain } from "@suaveplan/network-bootstrap";
|
||||
import {
|
||||
GunDBDiscovery,
|
||||
publicKeyHex,
|
||||
type GunDBEventMap,
|
||||
} from "@suaveplan/network-discovery-gundb";
|
||||
|
||||
const bus = new EventBus<GunDBEventMap>();
|
||||
const registry = new ServiceRegistry();
|
||||
const signingKey = crypto.getRandomValues(new Uint8Array(32));
|
||||
|
||||
bus.on("gundb:peer-discovered", ({ peer }) => {
|
||||
console.log("peer:", peer.id, peer.addresses);
|
||||
});
|
||||
bus.on("gundb:relay-error", ({ reason }) => {
|
||||
console.warn("relay:", reason);
|
||||
});
|
||||
|
||||
const discovery = new GunDBDiscovery({
|
||||
peers: [
|
||||
"wss://relay-a.example.com/gun",
|
||||
"wss://relay-b.example.com/gun",
|
||||
],
|
||||
room: "my-app/v1",
|
||||
maxPeers: 256,
|
||||
announceIntervalMs: 15_000,
|
||||
gunFactory: async (cfg) => {
|
||||
const { default: Gun } = await import("gun");
|
||||
return Gun({
|
||||
peers: cfg.peers as string[],
|
||||
localStorage: cfg.localStorage,
|
||||
}) as unknown as GunNodeLike;
|
||||
},
|
||||
localPeerId: publicKeyHex(signingKey),
|
||||
signingKey,
|
||||
bus,
|
||||
registry,
|
||||
});
|
||||
|
||||
const chain = new DiscoveryChain([discovery]);
|
||||
const peers = await chain.discover(5_000);
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
See sibling co-located markdown:
|
||||
|
||||
- [`src/types/types.md`](./src/types/types.md)
|
||||
- [`src/errors/errors.md`](./src/errors/errors.md)
|
||||
- [`src/otel/otel.md`](./src/otel/otel.md)
|
||||
- [`src/signing/signing.md`](./src/signing/signing.md)
|
||||
- [`src/core/gundb-discovery/gundb-discovery.md`](./src/core/gundb-discovery/gundb-discovery.md)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user