@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.
- package/README.md +192 -0
- package/dist/cli.js +146 -1
- package/dist/cli.js.map +1 -1
- package/dist/discovery/bootstrap.d.ts +32 -0
- package/dist/discovery/bootstrap.d.ts.map +1 -0
- package/dist/discovery/bootstrap.js +36 -0
- package/dist/discovery/bootstrap.js.map +1 -0
- package/dist/discovery/peer-discovery.d.ts +59 -0
- package/dist/discovery/peer-discovery.d.ts.map +1 -0
- package/dist/discovery/peer-discovery.js +108 -0
- package/dist/discovery/peer-discovery.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/message/envelope.d.ts +1 -1
- package/dist/message/envelope.d.ts.map +1 -1
- package/dist/message/envelope.js.map +1 -1
- package/dist/message/types/peer-discovery.d.ts +78 -0
- package/dist/message/types/peer-discovery.d.ts.map +1 -0
- package/dist/message/types/peer-discovery.js +90 -0
- package/dist/message/types/peer-discovery.js.map +1 -0
- package/dist/registry/discovery-service.d.ts +64 -0
- package/dist/registry/discovery-service.d.ts.map +1 -0
- package/dist/registry/discovery-service.js +129 -0
- package/dist/registry/discovery-service.js.map +1 -0
- package/dist/registry/messages.d.ts +55 -0
- package/dist/registry/messages.d.ts.map +1 -1
- package/dist/relay/server.d.ts +16 -0
- package/dist/relay/server.d.ts.map +1 -1
- package/dist/relay/server.js +73 -1
- package/dist/relay/server.js.map +1 -1
- package/package.json +43 -1
|
@@ -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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/message/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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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"}
|