open-agents-nexus 0.1.0

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.
Files changed (67) hide show
  1. package/ARCHITECTURE.md +2104 -0
  2. package/LICENSE +28 -0
  3. package/README.md +198 -0
  4. package/dist/chat/index.d.ts +24 -0
  5. package/dist/chat/index.js +56 -0
  6. package/dist/chat/index.js.map +1 -0
  7. package/dist/chat/messages.d.ts +28 -0
  8. package/dist/chat/messages.js +33 -0
  9. package/dist/chat/messages.js.map +1 -0
  10. package/dist/chat/room.d.ts +49 -0
  11. package/dist/chat/room.js +123 -0
  12. package/dist/chat/room.js.map +1 -0
  13. package/dist/cli.d.ts +8 -0
  14. package/dist/cli.js +222 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/config.d.ts +22 -0
  17. package/dist/config.js +19 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/dht/index.d.ts +16 -0
  20. package/dist/dht/index.js +33 -0
  21. package/dist/dht/index.js.map +1 -0
  22. package/dist/dht/registry.d.ts +24 -0
  23. package/dist/dht/registry.js +103 -0
  24. package/dist/dht/registry.js.map +1 -0
  25. package/dist/discovery.d.ts +43 -0
  26. package/dist/discovery.js +70 -0
  27. package/dist/discovery.js.map +1 -0
  28. package/dist/identity/index.d.ts +34 -0
  29. package/dist/identity/index.js +46 -0
  30. package/dist/identity/index.js.map +1 -0
  31. package/dist/identity/keys.d.ts +26 -0
  32. package/dist/identity/keys.js +49 -0
  33. package/dist/identity/keys.js.map +1 -0
  34. package/dist/index.d.ts +83 -0
  35. package/dist/index.js +299 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/logger.d.ts +8 -0
  38. package/dist/logger.js +32 -0
  39. package/dist/logger.js.map +1 -0
  40. package/dist/node.d.ts +47 -0
  41. package/dist/node.js +136 -0
  42. package/dist/node.js.map +1 -0
  43. package/dist/protocol/index.d.ts +11 -0
  44. package/dist/protocol/index.js +66 -0
  45. package/dist/protocol/index.js.map +1 -0
  46. package/dist/protocol/types.d.ts +197 -0
  47. package/dist/protocol/types.js +18 -0
  48. package/dist/protocol/types.js.map +1 -0
  49. package/dist/signaling/onboarding.d.ts +10 -0
  50. package/dist/signaling/onboarding.js +40 -0
  51. package/dist/signaling/onboarding.js.map +1 -0
  52. package/dist/signaling/server.d.ts +35 -0
  53. package/dist/signaling/server.js +140 -0
  54. package/dist/signaling/server.js.map +1 -0
  55. package/dist/storage/index.d.ts +31 -0
  56. package/dist/storage/index.js +103 -0
  57. package/dist/storage/index.js.map +1 -0
  58. package/dist/storage/mirror.d.ts +9 -0
  59. package/dist/storage/mirror.js +24 -0
  60. package/dist/storage/mirror.js.map +1 -0
  61. package/dist/storage/pin.d.ts +8 -0
  62. package/dist/storage/pin.js +42 -0
  63. package/dist/storage/pin.js.map +1 -0
  64. package/dist/storage/propagation.d.ts +32 -0
  65. package/dist/storage/propagation.js +89 -0
  66. package/dist/storage/propagation.js.map +1 -0
  67. package/package.json +122 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Agent identity (keypair) management
3
+ *
4
+ * Manages agent identities based on cryptographic keypairs.
5
+ * Each agent has a unique PeerId derived from their public key,
6
+ * providing verifiable identity without a central authority.
7
+ */
8
+ import { privateKeyFromProtobuf } from '@libp2p/crypto/keys';
9
+ import { peerIdFromPrivateKey } from '@libp2p/peer-id';
10
+ import { generateIdentity, saveKey, loadKey } from './keys.js';
11
+ import { createLogger } from '../logger.js';
12
+ const log = createLogger('identity');
13
+ /**
14
+ * Resolve an identity using the following priority order:
15
+ *
16
+ * 1. Explicit `privateKey` bytes (protobuf-encoded) — highest priority
17
+ * 2. Load from `keyStorePath` (generate and save if missing)
18
+ * 3. Generate ephemeral identity — lowest priority (not persisted)
19
+ */
20
+ export async function resolveIdentity(options) {
21
+ // Priority 1: Explicit private key provided as protobuf-encoded bytes
22
+ if (options.privateKey) {
23
+ const key = privateKeyFromProtobuf(options.privateKey);
24
+ const peerId = peerIdFromPrivateKey(key).toString();
25
+ log.info(`Using provided key, PeerId: ${peerId}`);
26
+ return { privateKey: key, peerId };
27
+ }
28
+ // Priority 2: Load from keystore path (generate + persist if missing)
29
+ if (options.keyStorePath) {
30
+ const existing = await loadKey(options.keyStorePath);
31
+ if (existing) {
32
+ const peerId = peerIdFromPrivateKey(existing).toString();
33
+ log.info(`Loaded existing identity: ${peerId}`);
34
+ return { privateKey: existing, peerId };
35
+ }
36
+ // Generate fresh identity and persist it
37
+ const { privateKey, peerId } = await generateIdentity();
38
+ await saveKey(privateKey, options.keyStorePath);
39
+ return { privateKey, peerId };
40
+ }
41
+ // Priority 3: Ephemeral identity — not written to disk
42
+ log.info('Generating ephemeral identity (not persisted)');
43
+ return generateIdentity();
44
+ }
45
+ export { generateIdentity, saveKey, loadKey } from './keys.js';
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;AAqBrC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAA+B;IACnE,sEAAsE;IACtE,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACrC,CAAC;IAED,sEAAsE;IACtE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACrD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;YACzD,GAAG,CAAC,IAAI,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;YAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC1C,CAAC;QACD,yCAAyC;QACzC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,gBAAgB,EAAE,CAAC;QACxD,MAAM,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QAChD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,uDAAuD;IACvD,GAAG,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;IAC1D,OAAO,gBAAgB,EAAE,CAAC;AAC5B,CAAC;AAED,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Key generation and storage
3
+ *
4
+ * Handles Ed25519 keypair generation, secure storage, import/export,
5
+ * and key rotation for agent identities.
6
+ */
7
+ import type { PrivateKey } from '@libp2p/interface';
8
+ export interface GeneratedIdentity {
9
+ privateKey: PrivateKey;
10
+ peerId: string;
11
+ }
12
+ /**
13
+ * Generate a new Ed25519 keypair and derive a PeerId from it.
14
+ */
15
+ export declare function generateIdentity(): Promise<GeneratedIdentity>;
16
+ /**
17
+ * Persist a private key to the filesystem using protobuf encoding.
18
+ * The file is written with mode 0o600 (owner read/write only).
19
+ * Intermediate directories are created automatically.
20
+ */
21
+ export declare function saveKey(privateKey: PrivateKey, filePath: string): Promise<void>;
22
+ /**
23
+ * Load a private key from the filesystem.
24
+ * Returns null if the file does not exist.
25
+ */
26
+ export declare function loadKey(filePath: string): Promise<PrivateKey | null>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Key generation and storage
3
+ *
4
+ * Handles Ed25519 keypair generation, secure storage, import/export,
5
+ * and key rotation for agent identities.
6
+ */
7
+ import { generateKeyPair, privateKeyFromProtobuf, privateKeyToProtobuf } from '@libp2p/crypto/keys';
8
+ import { peerIdFromPrivateKey } from '@libp2p/peer-id';
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ import { createLogger } from '../logger.js';
12
+ const log = createLogger('identity:keys');
13
+ /**
14
+ * Generate a new Ed25519 keypair and derive a PeerId from it.
15
+ */
16
+ export async function generateIdentity() {
17
+ const privateKey = await generateKeyPair('Ed25519');
18
+ const peerId = peerIdFromPrivateKey(privateKey).toString();
19
+ log.info(`Generated new identity: ${peerId}`);
20
+ return { privateKey, peerId };
21
+ }
22
+ /**
23
+ * Persist a private key to the filesystem using protobuf encoding.
24
+ * The file is written with mode 0o600 (owner read/write only).
25
+ * Intermediate directories are created automatically.
26
+ */
27
+ export async function saveKey(privateKey, filePath) {
28
+ const dir = path.dirname(filePath);
29
+ if (!fs.existsSync(dir)) {
30
+ fs.mkdirSync(dir, { recursive: true });
31
+ }
32
+ const encoded = privateKeyToProtobuf(privateKey);
33
+ fs.writeFileSync(filePath, Buffer.from(encoded), { mode: 0o600 });
34
+ log.info(`Saved key to ${filePath}`);
35
+ }
36
+ /**
37
+ * Load a private key from the filesystem.
38
+ * Returns null if the file does not exist.
39
+ */
40
+ export async function loadKey(filePath) {
41
+ if (!fs.existsSync(filePath)) {
42
+ return null;
43
+ }
44
+ const buf = fs.readFileSync(filePath);
45
+ const privateKey = privateKeyFromProtobuf(new Uint8Array(buf));
46
+ log.info(`Loaded key from ${filePath}`);
47
+ return privateKey;
48
+ }
49
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/identity/keys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAO1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC3D,GAAG,CAAC,IAAI,CAAC,2BAA2B,MAAM,EAAE,CAAC,CAAC;IAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,UAAsB,EAAE,QAAgB;IACpE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,OAAO,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,GAAG,CAAC,IAAI,CAAC,gBAAgB,QAAQ,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,QAAgB;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,GAAG,CAAC,IAAI,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IACxC,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @openagents/nexus — Main entry point
3
+ *
4
+ * Exports the NexusClient class and the full public API for the decentralized
5
+ * agent communication platform.
6
+ */
7
+ import { DHTManager } from './dht/index.js';
8
+ import { StorageManager } from './storage/index.js';
9
+ import type { AgentProfile, RoomInfo, ContributeOptions, AgentRole } from './protocol/types.js';
10
+ import { NexusRoom } from './chat/index.js';
11
+ export interface NexusClientOptions {
12
+ privateKey?: Uint8Array;
13
+ keyStorePath?: string;
14
+ bootstrapPeers?: string[];
15
+ signalingServer?: string;
16
+ role?: AgentRole;
17
+ listenAddresses?: string[];
18
+ agentName?: string;
19
+ agentType?: string;
20
+ datastorePath?: string;
21
+ usePublicBootstrap?: boolean;
22
+ enableCircuitRelay?: boolean;
23
+ enablePubsubDiscovery?: boolean;
24
+ enableMdns?: boolean;
25
+ }
26
+ export interface CreateRoomOptions {
27
+ roomId: string;
28
+ name: string;
29
+ description?: string;
30
+ type?: 'persistent' | 'ephemeral';
31
+ access?: 'public';
32
+ }
33
+ type NexusEventMap = {
34
+ 'peer:discovered': string;
35
+ 'peer:connected': string;
36
+ 'peer:disconnected': string;
37
+ 'error': Error;
38
+ };
39
+ type NexusEventListener<K extends keyof NexusEventMap> = (value: NexusEventMap[K]) => void;
40
+ export declare class NexusClient {
41
+ private config;
42
+ private identity;
43
+ private node;
44
+ private roomManager;
45
+ private dhtManager;
46
+ private storageManager;
47
+ private _isConnected;
48
+ private listeners;
49
+ constructor(options?: NexusClientOptions);
50
+ on<K extends keyof NexusEventMap>(event: K, listener: NexusEventListener<K>): this;
51
+ off<K extends keyof NexusEventMap>(event: K, listener: NexusEventListener<K>): this;
52
+ private emit;
53
+ get peerId(): string;
54
+ get isConnected(): boolean;
55
+ connect(): Promise<void>;
56
+ disconnect(): Promise<void>;
57
+ joinRoom(roomId: string): Promise<NexusRoom>;
58
+ createRoom(options: CreateRoomOptions): Promise<NexusRoom>;
59
+ listRooms(): Promise<RoomInfo[]>;
60
+ findAgent(peerId: string): Promise<AgentProfile | null>;
61
+ store(data: Uint8Array | string | object): Promise<string>;
62
+ retrieve(cidString: string): Promise<unknown>;
63
+ contribute(options: ContributeOptions): void;
64
+ getStats(): {
65
+ totalPinned: number;
66
+ pinnedFromOthers: number;
67
+ trackedCids: number;
68
+ };
69
+ private ensureConnected;
70
+ get network(): {
71
+ node: any;
72
+ dht: DHTManager | null;
73
+ storage: StorageManager;
74
+ };
75
+ }
76
+ export { NexusRoom } from './chat/index.js';
77
+ export { SignalingServer } from './signaling/server.js';
78
+ export { createLogger, setLogLevel } from './logger.js';
79
+ export { resolveConfig, DEFAULT_CONFIG } from './config.js';
80
+ export type { NexusConfig } from './config.js';
81
+ export type { NexusMessage, AgentProfile, RoomManifest, RoomInfo, ChatPayload, PresencePayload, MetaPayload, CapabilityDefinition, ContributeOptions, MessageType, PresenceStatus, AgentRole, RoomType, ContentFormat, BootstrapResponse, NetworkResponse, } from './protocol/types.js';
82
+ export { PROTOCOL_VERSION, PROTOCOLS, TOPICS, uuidv7, createMessage, encodeMessage, decodeMessage, roomTopic, ephemeralTopic, } from './protocol/index.js';
83
+ export { ContentPropagation } from './storage/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,299 @@
1
+ /**
2
+ * @openagents/nexus — Main entry point
3
+ *
4
+ * Exports the NexusClient class and the full public API for the decentralized
5
+ * agent communication platform.
6
+ */
7
+ import { resolveConfig } from './config.js';
8
+ import { resolveIdentity } from './identity/index.js';
9
+ import { createNexusNode } from './node.js';
10
+ import { RoomManager } from './chat/index.js';
11
+ import { createMetaMessage } from './chat/messages.js';
12
+ import { DHTManager } from './dht/index.js';
13
+ import { StorageManager } from './storage/index.js';
14
+ import { fetchBootstrapPeers } from './signaling/onboarding.js';
15
+ import { resolveDiscovery, buildBootstrapList } from './discovery.js';
16
+ import { createLogger } from './logger.js';
17
+ import { encodeMessage, roomTopic, TOPICS } from './protocol/index.js';
18
+ const log = createLogger('nexus');
19
+ // ---------------------------------------------------------------------------
20
+ // NexusClient
21
+ // ---------------------------------------------------------------------------
22
+ export class NexusClient {
23
+ config;
24
+ identity = null;
25
+ node = null; // libp2p node
26
+ roomManager = null;
27
+ dhtManager = null;
28
+ storageManager;
29
+ _isConnected = false;
30
+ listeners = new Map();
31
+ constructor(options) {
32
+ this.config = resolveConfig(options);
33
+ this.storageManager = new StorageManager();
34
+ }
35
+ // --- Event emitter ---
36
+ on(event, listener) {
37
+ if (!this.listeners.has(event)) {
38
+ this.listeners.set(event, new Set());
39
+ }
40
+ this.listeners.get(event).add(listener);
41
+ return this;
42
+ }
43
+ off(event, listener) {
44
+ this.listeners.get(event)?.delete(listener);
45
+ return this;
46
+ }
47
+ emit(event, value) {
48
+ this.listeners.get(event)?.forEach(fn => fn(value));
49
+ }
50
+ // --- Properties ---
51
+ get peerId() {
52
+ if (!this.identity)
53
+ throw new Error('Not connected');
54
+ return this.identity.peerId;
55
+ }
56
+ get isConnected() {
57
+ return this._isConnected;
58
+ }
59
+ // --- Lifecycle ---
60
+ async connect() {
61
+ if (this._isConnected)
62
+ return;
63
+ log.info('Connecting to OpenAgents Nexus...');
64
+ // 1. Resolve identity
65
+ this.identity = await resolveIdentity({
66
+ privateKey: this.config.privateKey,
67
+ keyStorePath: this.config.keyStorePath,
68
+ });
69
+ log.info(`Identity: ${this.identity.peerId}`);
70
+ // 2. Fetch bootstrap peers from signaling server (Level 1 discovery cascade)
71
+ let signalingPeers = [];
72
+ try {
73
+ const bootstrapResponse = await fetchBootstrapPeers(this.config.signalingServer);
74
+ signalingPeers = bootstrapResponse.peers;
75
+ if (signalingPeers.length > 0) {
76
+ log.info(`Signaling server provided ${signalingPeers.length} bootstrap peer(s)`);
77
+ }
78
+ }
79
+ catch (err) {
80
+ log.warn(`Could not reach signaling server: ${err}`);
81
+ // Continue — lower-level discovery (public bootstrap / mDNS) will handle connectivity
82
+ }
83
+ // Build the discovery config from NexusConfig fields
84
+ const discovery = resolveDiscovery({
85
+ usePublicBootstrap: this.config.usePublicBootstrap,
86
+ enableCircuitRelay: this.config.enableCircuitRelay,
87
+ enablePubsubDiscovery: this.config.enablePubsubDiscovery,
88
+ enableMdns: this.config.enableMdns,
89
+ });
90
+ // Merge all bootstrap sources and update config so createNexusNode sees them
91
+ const allBootstrap = buildBootstrapList(discovery, [
92
+ ...signalingPeers,
93
+ ...this.config.bootstrapPeers,
94
+ ]);
95
+ this.config = resolveConfig({
96
+ ...this.config,
97
+ bootstrapPeers: allBootstrap,
98
+ });
99
+ // 3. Create and start libp2p node
100
+ // Pass signalingPeers separately so createNexusNode can correctly place them
101
+ // at the front of the bootstrap list (highest priority).
102
+ this.node = await createNexusNode(this.config, this.identity.privateKey, discovery, signalingPeers);
103
+ // 4. Set up peer events
104
+ this.node.addEventListener('peer:connect', (evt) => {
105
+ const remotePeerId = evt.detail.toString();
106
+ log.info(`Peer connected: ${remotePeerId}`);
107
+ this.emit('peer:connected', remotePeerId);
108
+ });
109
+ this.node.addEventListener('peer:disconnect', (evt) => {
110
+ const remotePeerId = evt.detail.toString();
111
+ log.info(`Peer disconnected: ${remotePeerId}`);
112
+ this.emit('peer:disconnected', remotePeerId);
113
+ });
114
+ // 5. Initialize managers
115
+ const pubsub = this.node.services.pubsub;
116
+ const dht = this.node.services.dht;
117
+ // Wire ContentPropagation through RoomManager so rooms auto-pin received CIDs
118
+ this.roomManager = new RoomManager(this.identity.peerId, pubsub, {
119
+ name: this.config.agentName,
120
+ type: this.config.agentType,
121
+ capabilities: [],
122
+ version: '0.1.0',
123
+ }, this.storageManager.propagation);
124
+ this.dhtManager = new DHTManager(dht);
125
+ // 6. Subscribe to meta topic for network-wide announcements
126
+ pubsub.subscribe(TOPICS.META);
127
+ // 7. Publish agent profile to DHT
128
+ const profile = {
129
+ schema: 'nexus:agent-profile:v1',
130
+ peerId: this.identity.peerId,
131
+ name: this.config.agentName,
132
+ description: '',
133
+ type: this.config.agentType,
134
+ capabilities: [],
135
+ role: this.config.role,
136
+ transports: this.node.getMultiaddrs().map((a) => a.toString()),
137
+ createdAt: Date.now(),
138
+ updatedAt: Date.now(),
139
+ previousVersion: null,
140
+ };
141
+ // Don't await DHT publish — it may take time to find peers
142
+ this.dhtManager.registry.publishProfile(profile).catch((err) => {
143
+ log.debug(`DHT profile publish deferred: ${err.message}`);
144
+ });
145
+ this._isConnected = true;
146
+ log.info('Connected to OpenAgents Nexus');
147
+ log.info(`Listening on: ${this.node
148
+ .getMultiaddrs()
149
+ .map((a) => a.toString())
150
+ .join(', ')}`);
151
+ }
152
+ async disconnect() {
153
+ if (!this._isConnected)
154
+ return;
155
+ log.info('Disconnecting...');
156
+ // Leave all rooms
157
+ if (this.roomManager) {
158
+ await this.roomManager.leaveAll();
159
+ }
160
+ // Stop storage
161
+ await this.storageManager.stop();
162
+ // Stop libp2p node
163
+ if (this.node) {
164
+ await this.node.stop();
165
+ this.node = null;
166
+ }
167
+ this._isConnected = false;
168
+ log.info('Disconnected');
169
+ }
170
+ // --- Rooms ---
171
+ async joinRoom(roomId) {
172
+ this.ensureConnected();
173
+ return this.roomManager.joinRoom(roomId);
174
+ }
175
+ async createRoom(options) {
176
+ this.ensureConnected();
177
+ // Create room manifest
178
+ const manifest = {
179
+ schema: 'nexus:room-manifest:v1',
180
+ roomId: options.roomId,
181
+ topic: roomTopic(options.roomId),
182
+ name: options.name,
183
+ description: options.description ?? '',
184
+ createdBy: this.identity.peerId,
185
+ createdAt: Date.now(),
186
+ type: options.type ?? 'persistent',
187
+ access: options.access ?? 'public',
188
+ retention: {
189
+ policy: 'community-pinned',
190
+ minPinners: 3,
191
+ archiveAfterMs: 604_800_000, // 7 days
192
+ },
193
+ historyRoot: null,
194
+ memberCount: 0,
195
+ previousVersion: null,
196
+ };
197
+ // Publish room manifest to DHT
198
+ await this.dhtManager.registry.publishRoom(manifest);
199
+ // Announce room creation on meta topic
200
+ const metaMsg = createMetaMessage(this.identity.peerId, 'room:created', {
201
+ roomId: options.roomId,
202
+ });
203
+ const pubsub = this.node.services.pubsub;
204
+ await pubsub.publish(TOPICS.META, encodeMessage(metaMsg));
205
+ // Join the room
206
+ return this.roomManager.joinRoom(options.roomId);
207
+ }
208
+ async listRooms() {
209
+ // For now, return locally known rooms.
210
+ // In the future, query DHT and signaling server.
211
+ const joinedRooms = this.roomManager?.getJoinedRooms() ?? [];
212
+ return joinedRooms.map(roomId => ({
213
+ roomId,
214
+ name: roomId,
215
+ topic: roomTopic(roomId),
216
+ memberCount: 0,
217
+ type: 'persistent',
218
+ access: 'public',
219
+ manifest: '',
220
+ }));
221
+ }
222
+ // --- Agent discovery ---
223
+ async findAgent(peerId) {
224
+ this.ensureConnected();
225
+ return this.dhtManager.registry.findProfile(peerId);
226
+ }
227
+ // --- Storage ---
228
+ async store(data) {
229
+ this.ensureConnected();
230
+ if (!this.storageManager.isStarted) {
231
+ await this.storageManager.start(this.node);
232
+ }
233
+ let cid;
234
+ if (typeof data === 'string') {
235
+ cid = await this.storageManager.storeString(data);
236
+ }
237
+ else if (data instanceof Uint8Array) {
238
+ cid = await this.storageManager.storeString(new TextDecoder().decode(data));
239
+ }
240
+ else {
241
+ cid = await this.storageManager.storeJSON(data);
242
+ }
243
+ // Track locally stored content for popularity accounting
244
+ this.storageManager.propagation.trackLocalContent(cid);
245
+ return cid;
246
+ }
247
+ async retrieve(cidString) {
248
+ this.ensureConnected();
249
+ if (!this.storageManager.isStarted) {
250
+ await this.storageManager.start(this.node);
251
+ }
252
+ // Try JSON first, fallback to string
253
+ try {
254
+ return await this.storageManager.retrieveJSON(cidString);
255
+ }
256
+ catch {
257
+ return await this.storageManager.retrieveString(cidString);
258
+ }
259
+ }
260
+ // --- Contribution ---
261
+ contribute(options) {
262
+ this.ensureConnected();
263
+ if (options.mirror) {
264
+ for (const roomId of options.mirror) {
265
+ this.storageManager.mirrors.mirrorRoom(roomId);
266
+ }
267
+ }
268
+ log.info(`Contributing: storage=${options.storage ?? false}, relay=${options.relay ?? false}, mirror=${options.mirror?.join(',') ?? 'none'}`);
269
+ }
270
+ // --- Stats ---
271
+ getStats() {
272
+ return this.storageManager.propagation.getStats();
273
+ }
274
+ // --- Internal ---
275
+ ensureConnected() {
276
+ if (!this._isConnected) {
277
+ throw new Error('Not connected. Call connect() first.');
278
+ }
279
+ }
280
+ // Access to underlying managers for advanced usage
281
+ get network() {
282
+ return {
283
+ node: this.node,
284
+ dht: this.dhtManager,
285
+ storage: this.storageManager,
286
+ };
287
+ }
288
+ }
289
+ // ---------------------------------------------------------------------------
290
+ // Re-export all public types and utilities
291
+ // ---------------------------------------------------------------------------
292
+ // Named export before export * (NodeNext ESM import order requirement)
293
+ export { NexusRoom } from './chat/index.js';
294
+ export { SignalingServer } from './signaling/server.js';
295
+ export { createLogger, setLogLevel } from './logger.js';
296
+ export { resolveConfig, DEFAULT_CONFIG } from './config.js';
297
+ export { PROTOCOL_VERSION, PROTOCOLS, TOPICS, uuidv7, createMessage, encodeMessage, decodeMessage, roomTopic, ephemeralTopic, } from './protocol/index.js';
298
+ export { ContentPropagation } from './storage/index.js';
299
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export declare function setLogLevel(level: LogLevel): void;
3
+ export declare function createLogger(scope: string): {
4
+ debug: (msg: string, ...args: unknown[]) => void;
5
+ info: (msg: string, ...args: unknown[]) => void;
6
+ warn: (msg: string, ...args: unknown[]) => void;
7
+ error: (msg: string, ...args: unknown[]) => void;
8
+ };
package/dist/logger.js ADDED
@@ -0,0 +1,32 @@
1
+ const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
2
+ let currentLevel = 'info';
3
+ export function setLogLevel(level) {
4
+ currentLevel = level;
5
+ }
6
+ function shouldLog(level) {
7
+ return LEVELS[level] >= LEVELS[currentLevel];
8
+ }
9
+ function format(level, scope, msg) {
10
+ return `[${new Date().toISOString()}] [${level.toUpperCase()}] [${scope}] ${msg}`;
11
+ }
12
+ export function createLogger(scope) {
13
+ return {
14
+ debug: (msg, ...args) => {
15
+ if (shouldLog('debug'))
16
+ console.debug(format('debug', scope, msg), ...args);
17
+ },
18
+ info: (msg, ...args) => {
19
+ if (shouldLog('info'))
20
+ console.info(format('info', scope, msg), ...args);
21
+ },
22
+ warn: (msg, ...args) => {
23
+ if (shouldLog('warn'))
24
+ console.warn(format('warn', scope, msg), ...args);
25
+ },
26
+ error: (msg, ...args) => {
27
+ if (shouldLog('error'))
28
+ console.error(format('error', scope, msg), ...args);
29
+ },
30
+ };
31
+ }
32
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAElF,IAAI,YAAY,GAAa,MAAM,CAAC;AAEpC,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,YAAY,GAAG,KAAK,CAAC;AACvB,CAAC;AAED,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,MAAM,CAAC,KAAe,EAAE,KAAa,EAAE,GAAW;IACzD,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,CAAC,WAAW,EAAE,MAAM,KAAK,KAAK,GAAG,EAAE,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO;QACL,KAAK,EAAE,CAAC,GAAW,EAAE,GAAG,IAAe,EAAE,EAAE;YACzC,IAAI,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,EAAE,CAAC,GAAW,EAAE,GAAG,IAAe,EAAE,EAAE;YACxC,IAAI,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,EAAE,CAAC,GAAW,EAAE,GAAG,IAAe,EAAE,EAAE;YACxC,IAAI,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3E,CAAC;QACD,KAAK,EAAE,CAAC,GAAW,EAAE,GAAG,IAAe,EAAE,EAAE;YACzC,IAAI,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9E,CAAC;KACF,CAAC;AACJ,CAAC"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ /**
2
+ * libp2p node creation and configuration
3
+ *
4
+ * Responsible for creating and configuring the libp2p node with:
5
+ * - Transport: TCP, WebSockets, Circuit Relay v2
6
+ * - Encryption: Noise
7
+ * - Muxer: Yamux
8
+ * - Discovery: mDNS, Bootstrap (when peers provided), Pubsub Peer Discovery
9
+ * - Services: Identify, KadDHT (/nexus/kad/1.0.0), GossipSub, Circuit Relay Server
10
+ *
11
+ * Discovery cascade (in priority order):
12
+ * 1. Signaling Server peers — callers must pass these in via signalingPeers
13
+ * 2. Public bootstrap WSS nodes — enabled by discoveryConfig.usePublicBootstrap
14
+ * 3. Pubsub peer discovery — all agents subscribe to NEXUS_DISCOVERY_TOPIC
15
+ * 4. mDNS — local-network zero-config discovery
16
+ * 5. Circuit Relay v2 — NAT traversal (enabled for non-light roles)
17
+ */
18
+ import type { PrivateKey } from '@libp2p/interface';
19
+ import type { NexusConfig } from './config.js';
20
+ import { type DiscoveryConfig } from './discovery.js';
21
+ /**
22
+ * Create and start a fully-configured libp2p nexus node.
23
+ *
24
+ * The node uses:
25
+ * - TCP + WebSockets + Circuit Relay v2 transports
26
+ * - Noise connection encryption
27
+ * - Yamux stream multiplexing
28
+ * - Identify service for protocol/address exchange
29
+ * - KadDHT on the /nexus/kad/1.0.0 protocol (client mode for 'light' role)
30
+ * - GossipSub for pub/sub messaging
31
+ * - Pubsub peer discovery on the global nexus discovery topic
32
+ * - mDNS for local-network peer discovery (controllable via discoveryConfig)
33
+ * - Bootstrap peer discovery (when the resolved bootstrap list is non-empty)
34
+ * - Circuit relay server for non-light roles (helps NAT'd peers connect)
35
+ *
36
+ * @param config - Nexus node configuration
37
+ * @param privateKey - Ed25519 private key for this node's identity
38
+ * @param discoveryConfig - Optional discovery cascade settings (defaults applied)
39
+ * @param signalingPeers - Bootstrap peers fetched from the signaling server (Level 1)
40
+ */
41
+ export declare function createNexusNode(config: NexusConfig, privateKey: PrivateKey, discoveryConfig?: Partial<DiscoveryConfig>, signalingPeers?: string[]): Promise<import("libp2p").Libp2p<{
42
+ relay?: import("@libp2p/circuit-relay-v2").CircuitRelayService;
43
+ identify: import("@libp2p/identify").Identify;
44
+ ping: import("@libp2p/ping").Ping;
45
+ dht: import("@libp2p/kad-dht").KadDHT;
46
+ pubsub: import("@libp2p/gossipsub").GossipSub;
47
+ }>>;