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.
- package/ARCHITECTURE.md +2104 -0
- package/LICENSE +28 -0
- package/README.md +198 -0
- package/dist/chat/index.d.ts +24 -0
- package/dist/chat/index.js +56 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/messages.d.ts +28 -0
- package/dist/chat/messages.js +33 -0
- package/dist/chat/messages.js.map +1 -0
- package/dist/chat/room.d.ts +49 -0
- package/dist/chat/room.js +123 -0
- package/dist/chat/room.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +222 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -0
- package/dist/dht/index.d.ts +16 -0
- package/dist/dht/index.js +33 -0
- package/dist/dht/index.js.map +1 -0
- package/dist/dht/registry.d.ts +24 -0
- package/dist/dht/registry.js +103 -0
- package/dist/dht/registry.js.map +1 -0
- package/dist/discovery.d.ts +43 -0
- package/dist/discovery.js +70 -0
- package/dist/discovery.js.map +1 -0
- package/dist/identity/index.d.ts +34 -0
- package/dist/identity/index.js +46 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/keys.d.ts +26 -0
- package/dist/identity/keys.js +49 -0
- package/dist/identity/keys.js.map +1 -0
- package/dist/index.d.ts +83 -0
- package/dist/index.js +299 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +8 -0
- package/dist/logger.js +32 -0
- package/dist/logger.js.map +1 -0
- package/dist/node.d.ts +47 -0
- package/dist/node.js +136 -0
- package/dist/node.js.map +1 -0
- package/dist/protocol/index.d.ts +11 -0
- package/dist/protocol/index.js +66 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/types.d.ts +197 -0
- package/dist/protocol/types.js +18 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/signaling/onboarding.d.ts +10 -0
- package/dist/signaling/onboarding.js +40 -0
- package/dist/signaling/onboarding.js.map +1 -0
- package/dist/signaling/server.d.ts +35 -0
- package/dist/signaling/server.js +140 -0
- package/dist/signaling/server.js.map +1 -0
- package/dist/storage/index.d.ts +31 -0
- package/dist/storage/index.js +103 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/mirror.d.ts +9 -0
- package/dist/storage/mirror.js +24 -0
- package/dist/storage/mirror.js.map +1 -0
- package/dist/storage/pin.d.ts +8 -0
- package/dist/storage/pin.js +42 -0
- package/dist/storage/pin.js.map +1 -0
- package/dist/storage/propagation.d.ts +32 -0
- package/dist/storage/propagation.js +89 -0
- package/dist/storage/propagation.js.map +1 -0
- 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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -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
|
+
}>>;
|