Files
2026-05-27 23:47:53 +01:00

12 KiB

@suaveplan/network-transport-libp2p - Universal libp2p Transport for @suaveplan/network — WebSockets/WebRTC sub-transports with Noise + Yamux, identify + ping + bootstrap + circuit-relay-v2, fully injectable libp2p factory

Summary

Universal libp2p Transport for @suaveplan/network. Composes WebSockets or WebRTC sub-transports with Noise + Yamux, identify + ping + bootstrap + circuit-relay-v2, all wired through an injectable libp2p factory so the package itself never bundles libp2p at module-eval.

Documentation tree

  • connection — (no submodules)
  • errors — (no submodules)
  • frame — Implements length-prefixed binary framing for envelopes traversing a libp2p stream. Each frame is a 4-byte big-endian l…
  • peer-message — Defines the wire-format codec for envelopes flowing between libp2p peers. Encoding uses the @suaveplan/serialize Mess…
  • send — Outbound stream-based envelope shipping over libp2p. Each send opens a new protocol stream, writes a single framed en…
  • otel — (no submodules)
    • otel — (no submodules)
  • plugin — (no submodules)
  • streams — (no submodules)
  • transport — (no submodules)
  • types — (no submodules)
    • types — (no submodules)
- [connection](./src/connection/connection.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [errors](./src/errors/errors.md) — _(no submodules)_- [frame](./src/messaging/frame.md) — Implements length-prefixed binary framing for envelopes traversing a libp2p stream. Each frame is a 4-byte big-endian l…
  • peer-message — Defines the wire-format codec for envelopes flowing between libp2p peers. Encoding uses the @suaveplan/serialize Mess…
  • send — Outbound stream-based envelope shipping over libp2p. Each send opens a new protocol stream, writes a single framed en…
  • otel — (no submodules)- otel — (no submodules)- plugin — (no submodules)- plugin — (no submodules)- streams — (no submodules)- streams — (no submodules)- transport — (no submodules)- transport — (no submodules)- types — (no submodules)- types — (no submodules)- connection — (no submodules)- errors — (no submodules)- errors — (no submodules)- frame — Implements length-prefixed binary framing for envelopes traversing a libp2p stream. Each frame is a 4-byte big-endian l…
  • peer-message — Defines the wire-format codec for envelopes flowing between libp2p peers. Encoding uses the @suaveplan/serialize Mess…
  • send — Outbound stream-based envelope shipping over libp2p. Each send opens a new protocol stream, writes a single framed en…
  • otel — (no submodules)- otel — (no submodules)- plugin — (no submodules)- plugin — (no submodules)- streams — (no submodules)- streams — (no submodules)- transport — (no submodules)- transport — (no submodules)- types — (no submodules)- types — (no submodules)- connection — (no submodules)- errors — (no submodules)- errors — (no submodules)- frame — Implements length-prefixed binary framing for envelopes traversing a libp2p stream. Each frame is a 4-byte big-endian l…
  • peer-message — Defines the wire-format codec for envelopes flowing between libp2p peers. Encoding uses the @suaveplan/serialize Mess…
  • send — Outbound stream-based envelope shipping over libp2p. Each send opens a new protocol stream, writes a single framed en…
  • otel — (no submodules)- otel — (no submodules)- plugin — (no submodules)- plugin — (no submodules)- streams — (no submodules)- streams — (no submodules)- transport — (no submodules)- transport — (no submodules)- types — (no submodules)- types — (no submodules)- connection — (no submodules)- errors — (no submodules) - errors — (no submodules)- frame — Implements length-prefixed binary framing for envelopes traversing a libp2p stream. Each frame is a 4-byte big-endian l…
  • peer-message — Defines the wire-format codec for envelopes flowing between libp2p peers. Encoding uses the @suaveplan/serialize Mess…
  • send — Outbound stream-based envelope shipping over libp2p. Each send opens a new protocol stream, writes a single framed en…
  • otel — (no submodules) - otel — (no submodules)- plugin — (no submodules) - plugin — (no submodules)- streams — (no submodules) - streams — (no submodules)- transport — (no submodules) - transport — (no submodules)- types — (no submodules) - types — (no submodules)

Install

bun add @suaveplan/network-transport-libp2p

Quick Start

import { Libp2pPlugin, Libp2pTransport } from "@suaveplan/network-transport-libp2p";

const transport = new Libp2pTransport({
    libp2pFactory: async (cfg) => {
        const { createLibp2p } = await import("libp2p");
        const { websockets } = await import("@libp2p/websockets");
        const { noise } = await import("@chainsafe/libp2p-noise");
        const { yamux } = await import("@chainsafe/libp2p-yamux");
        const { bootstrap } = await import("@libp2p/bootstrap");
        const { identify } = await import("@libp2p/identify");
        const { ping } = await import("@libp2p/ping");

        return (await createLibp2p({
            addresses: { listen: cfg.addresses.listen as string[] },
            transports: [websockets()],
            connectionEncryption: [noise()],
            streamMuxers: [yamux()],
            peerDiscovery: [bootstrap({ list: cfg.bootstrap as string[] })],
            services: { identify: identify(), ping: ping() },
            connectionManager: {
                maxConnections: cfg.maxConnections,
                dialTimeout: cfg.dialTimeoutMs,
            },
        })) as unknown as import("@suaveplan/network-transport-libp2p").Libp2pNodeLike;
    },
    bootstrap: ["/dns4/bootstrap.example/tcp/443/wss/p2p/Qm…"],
    subTransport: "websockets",
});

await transport.start();

Sub-Transport Selection

subTransport Default addresses.listen Notes
"websockets" (default) /ip4/0.0.0.0/tcp/0/ws Universal — works in browser and Node.
"webrtc" /webrtc Browser-tier sub-transport; relies on the libp2p webrtc module.

TCP and mDNS are deferred to a server-tier sibling package.

Plugin Wrapper

import { Libp2pPlugin } from "@suaveplan/network-transport-libp2p";

const plugin = new Libp2pPlugin({
    libp2pFactory,
    bootstrap: bootstrapList,
});
node.use(plugin);
await node.start();

Security & Hardening

  • bootstrap is mandatory — empty list rejected at construction with INVALID_OPTIONS. There is no public-bootstrap fallback.
  • libp2pFactory is mandatory — the package never falls back to a default libp2p constructor; callers control the security posture.
  • All public boundaries validated by Zod.
  • 11-code structured error registry.
  • AbortSignal threaded through every async path.
  • Default frame cap: 1 MiB. Default message timeout: 5 s. Default dial timeout: 10 s.

Observability

Instrument Type Attributes
libp2p.connections_opened_total counter outcome
libp2p.streams_opened_total counter —
libp2p.bytes_total counter direction
libp2p.dial_ms histogram —
libp2p.stream_ttfb_ms histogram —
libp2p.active_peers gauge —

Demo

The 749-line React demo lives in a separate Wave-7 package (@suaveplan/react-network-libp2p-demo) so this package stays React-free.

Module Layout