# OpenSpec Change: enterprise-server-network-libp2p-server - **Change ID**: enterprise-server-network-libp2p-server - **Package**: `@suaveplan/network-libp2p-server` - **Category**: server/network - **Target path**: `server/network/network-libp2p-server` - **Status**: SUPERSEDED-BY-GENESIS-WAVE - **Date**: 2026-04-24 - **Reference spec**: `/mnt/s/web/suaveplan/enterprise/network-libp2p-server.md` --- ## Summary Deliver `@suaveplan/network-libp2p-server` on the genesis branch from scratch at enterprise quality. The package provides a server-side libp2p node with TCP + WebSocket transports, noise encryption, yamux stream multiplexing, Kad-DHT peer discovery, GossipSub pub/sub, and a typed `Libp2pServerAdapter` facade. It exposes `start` / `stop`, `subscribe` / `publish` for topic-based messaging, `dialPeer`, and `peers` queries. Genesis adds Zod-validated options, `@suaveplan/error` codes, OTel spans/counters, retry on dial failures, and full integration tests using two in-process nodes. --- ## Current-state audit (genesis) Does not exist on genesis — fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | Typed `NETWORK_LIBP2P.*` error codes | | `@suaveplan/types` (`workspace:^`) | `LoggerLike` | | `@suaveplan/events` (`workspace:^`) | Internal event routing | | `@suaveplan/retry` (`workspace:^`) | Dial retry | | `@suaveplan/logger` (`workspace:^`) | Structured logs | | `zod` (`catalog:forms`) | Options validation | | `@opentelemetry/api` (`catalog:observability`) | Spans + gauges | | `libp2p` (`catalog:network`) | Core libp2p | | `@libp2p/tcp` / `@libp2p/websockets` / `@chainsafe/libp2p-noise` / `@chainsafe/libp2p-yamux` / `@libp2p/kad-dht` / `@chainsafe/libp2p-gossipsub` (all `catalog:network`) | Transport + protocol stack | | `tslib` (`catalog:build`) | Runtime helpers | --- ## Public API surface ```ts class Libp2pServerAdapter { constructor(options: Libp2pServerOptions) start(): Promise stop(): Promise peerId(): string multiaddrs(): string[] peers(): string[] dialPeer(multiaddr: string): Promise subscribe(topic: string, handler: (from: string, data: Uint8Array) => void): () => void publish(topic: string, data: Uint8Array): Promise isStarted(): boolean } function createLibp2pServerAdapter(options: Libp2pServerOptions): Libp2pServerAdapter interface Libp2pServerOptions { listenAddresses?: string[] // default: ['/ip4/0.0.0.0/tcp/0'] bootstrapPeers?: string[] dhtEnabled?: boolean // default: true gossipEnabled?: boolean // default: true logger?: LoggerLike } const Libp2pServerOptionsSchema: z.ZodSchema type Libp2pErrorCode = | 'NETWORK_LIBP2P_START_FAILED' | 'NETWORK_LIBP2P_DIAL_FAILED' | 'NETWORK_LIBP2P_PUBLISH_FAILED' | 'NETWORK_LIBP2P_STOP_FAILED' function registerLibp2pErrorCodes(): void ``` --- ## File layout ```text server/network/network-libp2p-server/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/index.ts types/ libp2p-server.types.ts libp2p-server.types.md adapter/ libp2p-server-adapter/ libp2p-server-adapter.ts libp2p-server-adapter.md libp2p-server-adapter.types.ts libp2p-server-adapter.test.ts index.ts tests/ integration.test.ts ``` --- ## Impact Downstream: platform network mesh features. Server-only — Node.js required. **Prerequisites on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/retry`, `@suaveplan/logger`.