@rookdaemon/agora 0.1.5 → 0.2.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.
@@ -0,0 +1,59 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { RelayClient } from '../relay/client.js';
3
+ import type { PeerListRequestPayload, PeerListResponsePayload, PeerReferralPayload } from '../message/types/peer-discovery.js';
4
+ /**
5
+ * Configuration for PeerDiscoveryService
6
+ */
7
+ export interface PeerDiscoveryConfig {
8
+ /** Agent's public key */
9
+ publicKey: string;
10
+ /** Agent's private key for signing */
11
+ privateKey: string;
12
+ /** RelayClient instance for communication */
13
+ relayClient: RelayClient;
14
+ /** Public key of the relay server (for sending peer list requests) */
15
+ relayPublicKey?: string;
16
+ }
17
+ /**
18
+ * Events emitted by PeerDiscoveryService
19
+ */
20
+ export interface PeerDiscoveryEvents {
21
+ /** Emitted when peers are discovered */
22
+ 'peers-discovered': (peers: PeerListResponsePayload['peers']) => void;
23
+ /** Emitted when a peer referral is received */
24
+ 'peer-referral': (referral: PeerReferralPayload, from: string) => void;
25
+ /** Emitted on errors */
26
+ 'error': (error: Error) => void;
27
+ }
28
+ /**
29
+ * Service for discovering peers on the Agora network
30
+ */
31
+ export declare class PeerDiscoveryService extends EventEmitter {
32
+ private config;
33
+ constructor(config: PeerDiscoveryConfig);
34
+ /**
35
+ * Request peer list from relay
36
+ */
37
+ discoverViaRelay(filters?: PeerListRequestPayload['filters']): Promise<PeerListResponsePayload | null>;
38
+ /**
39
+ * Send peer referral to another agent
40
+ */
41
+ referPeer(recipientPublicKey: string, referredPublicKey: string, metadata?: {
42
+ name?: string;
43
+ endpoint?: string;
44
+ comment?: string;
45
+ trustScore?: number;
46
+ }): Promise<{
47
+ ok: boolean;
48
+ error?: string;
49
+ }>;
50
+ /**
51
+ * Handle incoming peer referral
52
+ */
53
+ private handleReferral;
54
+ /**
55
+ * Handle incoming peer list from relay
56
+ */
57
+ private handlePeerList;
58
+ }
59
+ //# sourceMappingURL=peer-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-discovery.d.ts","sourceRoot":"","sources":["../../src/discovery/peer-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE/H;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,WAAW,EAAE,WAAW,CAAC;IACzB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,kBAAkB,EAAE,CAAC,KAAK,EAAE,uBAAuB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACtE,+CAA+C;IAC/C,eAAe,EAAE,CAAC,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvE,wBAAwB;IACxB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjC;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAcvC;;OAEG;IACG,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC;IAiD5G;;OAEG;IACG,SAAS,CACb,kBAAkB,EAAE,MAAM,EAC1B,iBAAiB,EAAE,MAAM,EACzB,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GACrF,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAuB3C;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,OAAO,CAAC,cAAc;CAiBvB"}
@@ -0,0 +1,108 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { createEnvelope, verifyEnvelope } from '../message/envelope.js';
3
+ /**
4
+ * Service for discovering peers on the Agora network
5
+ */
6
+ export class PeerDiscoveryService extends EventEmitter {
7
+ config;
8
+ constructor(config) {
9
+ super();
10
+ this.config = config;
11
+ // Listen for peer list responses and referrals
12
+ this.config.relayClient.on('message', (envelope, from) => {
13
+ if (envelope.type === 'peer_list_response') {
14
+ this.handlePeerList(envelope);
15
+ }
16
+ else if (envelope.type === 'peer_referral') {
17
+ this.handleReferral(envelope, from);
18
+ }
19
+ });
20
+ }
21
+ /**
22
+ * Request peer list from relay
23
+ */
24
+ async discoverViaRelay(filters) {
25
+ if (!this.config.relayPublicKey) {
26
+ throw new Error('Relay public key not configured');
27
+ }
28
+ if (!this.config.relayClient.connected()) {
29
+ throw new Error('Not connected to relay');
30
+ }
31
+ const payload = filters ? { filters } : {};
32
+ const envelope = createEnvelope('peer_list_request', this.config.publicKey, this.config.privateKey, payload);
33
+ // Send request to relay
34
+ const result = await this.config.relayClient.send(this.config.relayPublicKey, envelope);
35
+ if (!result.ok) {
36
+ throw new Error(`Failed to send peer list request: ${result.error}`);
37
+ }
38
+ // Wait for response (with timeout)
39
+ return new Promise((resolve, reject) => {
40
+ const timeout = setTimeout(() => {
41
+ cleanup();
42
+ reject(new Error('Peer list request timed out'));
43
+ }, 10000); // 10 second timeout
44
+ const messageHandler = (responseEnvelope, from) => {
45
+ if (responseEnvelope.type === 'peer_list_response' &&
46
+ responseEnvelope.inReplyTo === envelope.id &&
47
+ from === this.config.relayPublicKey) {
48
+ cleanup();
49
+ resolve(responseEnvelope.payload);
50
+ }
51
+ };
52
+ const cleanup = () => {
53
+ clearTimeout(timeout);
54
+ this.config.relayClient.off('message', messageHandler);
55
+ };
56
+ this.config.relayClient.on('message', messageHandler);
57
+ });
58
+ }
59
+ /**
60
+ * Send peer referral to another agent
61
+ */
62
+ async referPeer(recipientPublicKey, referredPublicKey, metadata) {
63
+ if (!this.config.relayClient.connected()) {
64
+ return { ok: false, error: 'Not connected to relay' };
65
+ }
66
+ const payload = {
67
+ publicKey: referredPublicKey,
68
+ endpoint: metadata?.endpoint,
69
+ metadata: metadata?.name ? { name: metadata.name } : undefined,
70
+ comment: metadata?.comment,
71
+ trustScore: metadata?.trustScore,
72
+ };
73
+ const envelope = createEnvelope('peer_referral', this.config.publicKey, this.config.privateKey, payload);
74
+ return this.config.relayClient.send(recipientPublicKey, envelope);
75
+ }
76
+ /**
77
+ * Handle incoming peer referral
78
+ */
79
+ handleReferral(envelope, from) {
80
+ // Verify envelope
81
+ const verification = verifyEnvelope(envelope);
82
+ if (!verification.valid) {
83
+ this.emit('error', new Error(`Invalid peer referral: ${verification.reason}`));
84
+ return;
85
+ }
86
+ // Emit event for application to handle
87
+ this.emit('peer-referral', envelope.payload, from);
88
+ }
89
+ /**
90
+ * Handle incoming peer list from relay
91
+ */
92
+ handlePeerList(envelope) {
93
+ // Verify envelope
94
+ const verification = verifyEnvelope(envelope);
95
+ if (!verification.valid) {
96
+ this.emit('error', new Error(`Invalid peer list response: ${verification.reason}`));
97
+ return;
98
+ }
99
+ // Verify sender is the relay
100
+ if (envelope.sender !== this.config.relayPublicKey) {
101
+ this.emit('error', new Error('Peer list response not from configured relay'));
102
+ return;
103
+ }
104
+ // Emit event
105
+ this.emit('peers-discovered', envelope.payload.peers);
106
+ }
107
+ }
108
+ //# sourceMappingURL=peer-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-discovery.js","sourceRoot":"","sources":["../../src/discovery/peer-discovery.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,11 +4,15 @@ export * from './registry/capability.js';
4
4
  export * from './registry/peer.js';
5
5
  export * from './registry/peer-store.js';
6
6
  export * from './registry/messages.js';
7
+ export * from './registry/discovery-service.js';
7
8
  export * from './message/types/paper-discovery.js';
9
+ export * from './message/types/peer-discovery.js';
8
10
  export * from './transport/http.js';
9
11
  export * from './transport/peer-config.js';
10
12
  export * from './config.js';
11
13
  export * from './relay/server.js';
12
14
  export * from './relay/client.js';
13
15
  export * from './relay/types.js';
16
+ export * from './discovery/peer-discovery.js';
17
+ export * from './discovery/bootstrap.js';
14
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AACnD,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -4,11 +4,15 @@ export * from './registry/capability.js';
4
4
  export * from './registry/peer.js';
5
5
  export * from './registry/peer-store.js';
6
6
  export * from './registry/messages.js';
7
+ export * from './registry/discovery-service.js';
7
8
  export * from './message/types/paper-discovery.js';
9
+ export * from './message/types/peer-discovery.js';
8
10
  export * from './transport/http.js';
9
11
  export * from './transport/peer-config.js';
10
12
  export * from './config.js';
11
13
  export * from './relay/server.js';
12
14
  export * from './relay/client.js';
13
15
  export * from './relay/types.js';
16
+ export * from './discovery/peer-discovery.js';
17
+ export * from './discovery/bootstrap.js';
14
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oCAAoC,CAAC;AACnD,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC"}
@@ -2,7 +2,7 @@
2
2
  * Message types on the Agora network.
3
3
  * Every piece of data flowing between agents is wrapped in an envelope.
4
4
  */
5
- export type MessageType = 'announce' | 'discover' | 'request' | 'response' | 'publish' | 'subscribe' | 'verify' | 'ack' | 'error' | 'paper_discovery';
5
+ export type MessageType = 'announce' | 'discover' | 'request' | 'response' | 'publish' | 'subscribe' | 'verify' | 'ack' | 'error' | 'paper_discovery' | 'peer_list_request' | 'peer_list_response' | 'peer_referral' | 'capability_announce' | 'capability_query' | 'capability_response';
6
6
  /**
7
7
  * The signed envelope that wraps every message on the network.
8
8
  * Content-addressed: the ID is the hash of the canonical payload.
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/message/envelope.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,WAAW,GACX,QAAQ,GACR,KAAK,GACL,OAAO,GACP,iBAAiB,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,WAAW,CAAC;IAClB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CACnB;AAgBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAM/H;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,EACV,SAAS,CAAC,EAAE,MAAM,GACjB,QAAQ,CAAC,CAAC,CAAC,CAeb;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAmBtF"}
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/message/envelope.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,UAAU,GACV,SAAS,GACT,UAAU,GACV,SAAS,GACT,WAAW,GACX,QAAQ,GACR,KAAK,GACL,OAAO,GACP,iBAAiB,GACjB,mBAAmB,GACnB,oBAAoB,GACpB,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,IAAI,EAAE,WAAW,CAAC;IAClB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;CACnB;AAgBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAM/H;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,CAAC,EACV,SAAS,CAAC,EAAE,MAAM,GACjB,QAAQ,CAAC,CAAC,CAAC,CAeb;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAmBtF"}
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/message/envelope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/message/envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA8CtE;;GAEG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC1D,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,eAAe,CAAE,KAAiC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9G,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAiB,EAAE,MAAc,EAAE,SAAiB,EAAE,OAAgB,EAAE,SAAkB;IACrH,MAAM,GAAG,GAA4B,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC1E,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAiB,EACjB,MAAc,EACd,UAAkB,EAClB,OAAU,EACV,SAAkB;IAElB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5E,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAErD,OAAO;QACL,EAAE;QACF,IAAI;QACJ,MAAM;QACN,SAAS;QACT,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,OAAO;QACP,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,QAAkB;IAC/C,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAEhF,6BAA6B;IAC7B,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAE5E,6BAA6B;IAC7B,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,EAAE,KAAK,UAAU,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACjD,CAAC;IAED,kBAAkB;IAClB,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACvD,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Peer discovery message types for the Agora network.
3
+ */
4
+ /**
5
+ * Request peer list from relay
6
+ */
7
+ export interface PeerListRequestPayload {
8
+ /** Optional filters */
9
+ filters?: {
10
+ /** Only peers seen in last N ms */
11
+ activeWithin?: number;
12
+ /** Maximum peers to return */
13
+ limit?: number;
14
+ };
15
+ }
16
+ /**
17
+ * Relay responds with connected peers
18
+ */
19
+ export interface PeerListResponsePayload {
20
+ /** List of known peers */
21
+ peers: Array<{
22
+ /** Peer's Ed25519 public key */
23
+ publicKey: string;
24
+ /** Optional metadata (if peer announced) */
25
+ metadata?: {
26
+ name?: string;
27
+ version?: string;
28
+ capabilities?: string[];
29
+ };
30
+ /** Last seen timestamp (ms) */
31
+ lastSeen: number;
32
+ }>;
33
+ /** Total peer count (may be > peers.length if limited) */
34
+ totalPeers: number;
35
+ /** Relay's public key (for trust verification) */
36
+ relayPublicKey: string;
37
+ }
38
+ /**
39
+ * Agent recommends another agent
40
+ */
41
+ export interface PeerReferralPayload {
42
+ /** Referred peer's public key */
43
+ publicKey: string;
44
+ /** Optional endpoint (if known) */
45
+ endpoint?: string;
46
+ /** Optional metadata */
47
+ metadata?: {
48
+ name?: string;
49
+ version?: string;
50
+ capabilities?: string[];
51
+ };
52
+ /** Referrer's comment */
53
+ comment?: string;
54
+ /** Trust hint (RFC-001 integration) */
55
+ trustScore?: number;
56
+ }
57
+ /**
58
+ * Validate PeerListRequestPayload
59
+ */
60
+ export declare function validatePeerListRequest(payload: unknown): {
61
+ valid: boolean;
62
+ errors: string[];
63
+ };
64
+ /**
65
+ * Validate PeerListResponsePayload
66
+ */
67
+ export declare function validatePeerListResponse(payload: unknown): {
68
+ valid: boolean;
69
+ errors: string[];
70
+ };
71
+ /**
72
+ * Validate PeerReferralPayload
73
+ */
74
+ export declare function validatePeerReferral(payload: unknown): {
75
+ valid: boolean;
76
+ errors: string[];
77
+ };
78
+ //# sourceMappingURL=peer-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-discovery.d.ts","sourceRoot":"","sources":["../../../src/message/types/peer-discovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uBAAuB;IACvB,OAAO,CAAC,EAAE;QACR,mCAAmC;QACnC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,8BAA8B;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,0BAA0B;IAC1B,KAAK,EAAE,KAAK,CAAC;QACX,gCAAgC;QAChC,SAAS,EAAE,MAAM,CAAC;QAClB,4CAA4C;QAC5C,QAAQ,CAAC,EAAE;YACT,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;SACzB,CAAC;QACF,+BAA+B;QAC/B,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;IACF,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAyB9F;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAqC/F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B3F"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Peer discovery message types for the Agora network.
3
+ */
4
+ /**
5
+ * Validate PeerListRequestPayload
6
+ */
7
+ export function validatePeerListRequest(payload) {
8
+ const errors = [];
9
+ if (typeof payload !== 'object' || payload === null) {
10
+ errors.push('Payload must be an object');
11
+ return { valid: false, errors };
12
+ }
13
+ const p = payload;
14
+ if (p.filters !== undefined) {
15
+ if (typeof p.filters !== 'object' || p.filters === null) {
16
+ errors.push('filters must be an object');
17
+ }
18
+ else {
19
+ const filters = p.filters;
20
+ if (filters.activeWithin !== undefined && typeof filters.activeWithin !== 'number') {
21
+ errors.push('filters.activeWithin must be a number');
22
+ }
23
+ if (filters.limit !== undefined && typeof filters.limit !== 'number') {
24
+ errors.push('filters.limit must be a number');
25
+ }
26
+ }
27
+ }
28
+ return { valid: errors.length === 0, errors };
29
+ }
30
+ /**
31
+ * Validate PeerListResponsePayload
32
+ */
33
+ export function validatePeerListResponse(payload) {
34
+ const errors = [];
35
+ if (typeof payload !== 'object' || payload === null) {
36
+ errors.push('Payload must be an object');
37
+ return { valid: false, errors };
38
+ }
39
+ const p = payload;
40
+ if (!Array.isArray(p.peers)) {
41
+ errors.push('peers must be an array');
42
+ }
43
+ else {
44
+ p.peers.forEach((peer, index) => {
45
+ if (typeof peer !== 'object' || peer === null) {
46
+ errors.push(`peers[${index}] must be an object`);
47
+ return;
48
+ }
49
+ const peerObj = peer;
50
+ if (typeof peerObj.publicKey !== 'string') {
51
+ errors.push(`peers[${index}].publicKey must be a string`);
52
+ }
53
+ if (typeof peerObj.lastSeen !== 'number') {
54
+ errors.push(`peers[${index}].lastSeen must be a number`);
55
+ }
56
+ });
57
+ }
58
+ if (typeof p.totalPeers !== 'number') {
59
+ errors.push('totalPeers must be a number');
60
+ }
61
+ if (typeof p.relayPublicKey !== 'string') {
62
+ errors.push('relayPublicKey must be a string');
63
+ }
64
+ return { valid: errors.length === 0, errors };
65
+ }
66
+ /**
67
+ * Validate PeerReferralPayload
68
+ */
69
+ export function validatePeerReferral(payload) {
70
+ const errors = [];
71
+ if (typeof payload !== 'object' || payload === null) {
72
+ errors.push('Payload must be an object');
73
+ return { valid: false, errors };
74
+ }
75
+ const p = payload;
76
+ if (typeof p.publicKey !== 'string') {
77
+ errors.push('publicKey must be a string');
78
+ }
79
+ if (p.endpoint !== undefined && typeof p.endpoint !== 'string') {
80
+ errors.push('endpoint must be a string');
81
+ }
82
+ if (p.comment !== undefined && typeof p.comment !== 'string') {
83
+ errors.push('comment must be a string');
84
+ }
85
+ if (p.trustScore !== undefined && typeof p.trustScore !== 'number') {
86
+ errors.push('trustScore must be a number');
87
+ }
88
+ return { valid: errors.length === 0, errors };
89
+ }
90
+ //# sourceMappingURL=peer-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-discovery.js","sourceRoot":"","sources":["../../../src/message/types/peer-discovery.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0DH;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,GAAG,OAAkC,CAAC;IAE7C,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACxD,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,CAAC,CAAC,OAAkC,CAAC;YACrD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;gBACnF,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YACvD,CAAC;YACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACrE,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,GAAG,OAAkC,CAAC;IAE7C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC9B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC9C,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,qBAAqB,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,MAAM,OAAO,GAAG,IAA+B,CAAC;YAChD,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC1C,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,8BAA8B,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,6BAA6B,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,GAAG,OAAkC,CAAC;IAE7C,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC7D,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnE,MAAM,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { type Envelope } from '../message/envelope.js';
2
+ import { PeerStore } from './peer-store.js';
3
+ import type { Capability } from './capability.js';
4
+ import type { CapabilityAnnouncePayload, CapabilityQueryPayload, CapabilityResponsePayload } from './messages.js';
5
+ /**
6
+ * DiscoveryService manages capability-based peer discovery.
7
+ * It maintains a local index of peer capabilities and handles
8
+ * capability announce, query, and response messages.
9
+ */
10
+ export declare class DiscoveryService {
11
+ private peerStore;
12
+ private identity;
13
+ constructor(peerStore: PeerStore, identity: {
14
+ publicKey: string;
15
+ privateKey: string;
16
+ });
17
+ /**
18
+ * Announce own capabilities to the network.
19
+ * Creates a capability_announce envelope that can be broadcast to peers.
20
+ *
21
+ * @param capabilities - List of capabilities this agent offers
22
+ * @param metadata - Optional metadata about this agent
23
+ * @returns A signed capability_announce envelope
24
+ */
25
+ announce(capabilities: Capability[], metadata?: {
26
+ name?: string;
27
+ version?: string;
28
+ }): Envelope<CapabilityAnnouncePayload>;
29
+ /**
30
+ * Handle an incoming capability_announce message.
31
+ * Updates the peer store with the announced capabilities.
32
+ *
33
+ * @param envelope - The capability_announce envelope to process
34
+ */
35
+ handleAnnounce(envelope: Envelope<CapabilityAnnouncePayload>): void;
36
+ /**
37
+ * Create a capability query payload.
38
+ *
39
+ * @param queryType - Type of query: 'name', 'tag', or 'schema'
40
+ * @param query - The query value (capability name, tag, or schema)
41
+ * @param filters - Optional filters (limit, minTrustScore)
42
+ * @returns A capability_query payload
43
+ */
44
+ query(queryType: 'name' | 'tag' | 'schema', query: string | object, filters?: {
45
+ limit?: number;
46
+ minTrustScore?: number;
47
+ }): CapabilityQueryPayload;
48
+ /**
49
+ * Handle an incoming capability_query message.
50
+ * Searches the local peer store and returns matching peers.
51
+ *
52
+ * @param envelope - The capability_query envelope to process
53
+ * @returns A capability_response envelope with matching peers
54
+ */
55
+ handleQuery(envelope: Envelope<CapabilityQueryPayload>): Envelope<CapabilityResponsePayload>;
56
+ /**
57
+ * Remove peers that haven't been seen within the specified time window.
58
+ *
59
+ * @param maxAgeMs - Maximum age in milliseconds
60
+ * @returns Number of peers removed
61
+ */
62
+ pruneStale(maxAgeMs: number): number;
63
+ }
64
+ //# sourceMappingURL=discovery-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-service.d.ts","sourceRoot":"","sources":["../../src/registry/discovery-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EAC1B,MAAM,eAAe,CAAC;AAEvB;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ;gBADR,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAG7D;;;;;;;OAOG;IACH,QAAQ,CACN,YAAY,EAAE,UAAU,EAAE,EAC1B,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC7C,QAAQ,CAAC,yBAAyB,CAAC;IAoBtC;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,IAAI;IAgBnE;;;;;;;OAOG;IACH,KAAK,CACH,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,EACpC,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GACnD,sBAAsB;IAQzB;;;;;;OAMG;IACH,WAAW,CACT,QAAQ,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GACzC,QAAQ,CAAC,yBAAyB,CAAC;IAqDtC;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAGrC"}
@@ -0,0 +1,129 @@
1
+ import { createEnvelope } from '../message/envelope.js';
2
+ /**
3
+ * DiscoveryService manages capability-based peer discovery.
4
+ * It maintains a local index of peer capabilities and handles
5
+ * capability announce, query, and response messages.
6
+ */
7
+ export class DiscoveryService {
8
+ peerStore;
9
+ identity;
10
+ constructor(peerStore, identity) {
11
+ this.peerStore = peerStore;
12
+ this.identity = identity;
13
+ }
14
+ /**
15
+ * Announce own capabilities to the network.
16
+ * Creates a capability_announce envelope that can be broadcast to peers.
17
+ *
18
+ * @param capabilities - List of capabilities this agent offers
19
+ * @param metadata - Optional metadata about this agent
20
+ * @returns A signed capability_announce envelope
21
+ */
22
+ announce(capabilities, metadata) {
23
+ const payload = {
24
+ publicKey: this.identity.publicKey,
25
+ capabilities,
26
+ metadata: metadata ? {
27
+ ...metadata,
28
+ lastSeen: Date.now(),
29
+ } : {
30
+ lastSeen: Date.now(),
31
+ },
32
+ };
33
+ return createEnvelope('capability_announce', this.identity.publicKey, this.identity.privateKey, payload);
34
+ }
35
+ /**
36
+ * Handle an incoming capability_announce message.
37
+ * Updates the peer store with the announced capabilities.
38
+ *
39
+ * @param envelope - The capability_announce envelope to process
40
+ */
41
+ handleAnnounce(envelope) {
42
+ const { payload } = envelope;
43
+ const peer = {
44
+ publicKey: payload.publicKey,
45
+ capabilities: payload.capabilities,
46
+ lastSeen: payload.metadata?.lastSeen || envelope.timestamp,
47
+ metadata: payload.metadata ? {
48
+ name: payload.metadata.name,
49
+ version: payload.metadata.version,
50
+ } : undefined,
51
+ };
52
+ this.peerStore.addOrUpdatePeer(peer);
53
+ }
54
+ /**
55
+ * Create a capability query payload.
56
+ *
57
+ * @param queryType - Type of query: 'name', 'tag', or 'schema'
58
+ * @param query - The query value (capability name, tag, or schema)
59
+ * @param filters - Optional filters (limit, minTrustScore)
60
+ * @returns A capability_query payload
61
+ */
62
+ query(queryType, query, filters) {
63
+ return {
64
+ queryType,
65
+ query,
66
+ filters,
67
+ };
68
+ }
69
+ /**
70
+ * Handle an incoming capability_query message.
71
+ * Searches the local peer store and returns matching peers.
72
+ *
73
+ * @param envelope - The capability_query envelope to process
74
+ * @returns A capability_response envelope with matching peers
75
+ */
76
+ handleQuery(envelope) {
77
+ const { payload } = envelope;
78
+ let peers = [];
79
+ // Execute query based on type
80
+ if (payload.queryType === 'name' && typeof payload.query === 'string') {
81
+ peers = this.peerStore.findByCapability(payload.query);
82
+ }
83
+ else if (payload.queryType === 'tag' && typeof payload.query === 'string') {
84
+ peers = this.peerStore.findByTag(payload.query);
85
+ }
86
+ else if (payload.queryType === 'schema') {
87
+ // Schema-based matching is deferred to Phase 2b
88
+ // For now, return empty results
89
+ peers = [];
90
+ }
91
+ // Apply filters
92
+ const limit = payload.filters?.limit;
93
+ const totalMatches = peers.length;
94
+ if (limit !== undefined && limit > 0) {
95
+ peers = peers.slice(0, limit);
96
+ }
97
+ // Transform peers to response format
98
+ const responsePeers = peers.map(peer => ({
99
+ publicKey: peer.publicKey,
100
+ capabilities: peer.capabilities,
101
+ metadata: peer.metadata ? {
102
+ name: peer.metadata.name,
103
+ version: peer.metadata.version,
104
+ lastSeen: peer.lastSeen,
105
+ } : {
106
+ lastSeen: peer.lastSeen,
107
+ },
108
+ // Trust score integration deferred to Phase 2b (RFC-001)
109
+ trustScore: undefined,
110
+ }));
111
+ const responsePayload = {
112
+ queryId: envelope.id,
113
+ peers: responsePeers,
114
+ totalMatches,
115
+ };
116
+ return createEnvelope('capability_response', this.identity.publicKey, this.identity.privateKey, responsePayload, envelope.id // inReplyTo
117
+ );
118
+ }
119
+ /**
120
+ * Remove peers that haven't been seen within the specified time window.
121
+ *
122
+ * @param maxAgeMs - Maximum age in milliseconds
123
+ * @returns Number of peers removed
124
+ */
125
+ pruneStale(maxAgeMs) {
126
+ return this.peerStore.prune(maxAgeMs);
127
+ }
128
+ }
129
+ //# sourceMappingURL=discovery-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-service.js","sourceRoot":"","sources":["../../src/registry/discovery-service.ts"],"names":[],"mappings":"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"}