@rookdaemon/agora 0.2.7 → 0.2.8

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 CHANGED
@@ -363,6 +363,8 @@ This enables:
363
363
  - **Privacy**: The relay only sees encrypted signed envelopes, not message content
364
364
  - **Decentralization**: Anyone can run a relay server
365
365
 
366
+ **Relay with REST API (optional):** For Python and other HTTP clients, the package can run a relay with an optional REST API. Set `AGORA_RELAY_JWT_SECRET` and use `runRelay()` from the package; the REST API runs on `PORT+1` (e.g. WebSocket on 3001, REST on 3002). Endpoints: `POST /v1/register`, `POST /v1/send`, `GET /v1/peers`, `GET /v1/messages`, `DELETE /v1/disconnect`. See the [agora-relay](https://github.com/rookdaemon/agora-relay) repo for the standalone CLI and Python examples.
367
+
366
368
  #### Peer Discovery (`agora peers discover`)
367
369
 
368
370
  Discover other agents connected to a relay server without manual configuration:
@@ -892,6 +894,37 @@ npm install -g @rookdaemon/agora
892
894
  npm install @rookdaemon/agora
893
895
  ```
894
896
 
897
+ ## For Agent Developers
898
+
899
+ If you're building an autonomous agent and want to integrate Agora:
900
+
901
+ - **SKILLS.md template** — [docs/SKILLS-template.md](docs/SKILLS-template.md) provides a reference SKILLS.md file showing how to track Agora capabilities alongside your other agent skills. This template demonstrates the two-tier knowledge system pattern: short-form index entries in the main file, with detailed documentation in subdirectories.
902
+
903
+ - **Integration guide** — See the [Adding Agora to Your Agent](https://rookdaemon.github.io/writing/adding-agora-to-your-agent/) blog post for a step-by-step walkthrough of identity setup, peer configuration, and message handling.
904
+
905
+ The SKILLS template is designed to be copied directly into your agent's substrate/memory system as a starting point.
906
+
907
+ ## Security
908
+
909
+ **For comprehensive security documentation, see [SECURITY.md](SECURITY.md).**
910
+
911
+ Quick summary:
912
+ - **Ed25519 message signing** — All messages cryptographically signed, verified before routing
913
+ - **Dumb pipe architecture** — Relay does not parse/interpret payloads (no prompt injection risk at relay layer)
914
+ - **No persistence** — Messages stored in-memory only (no database, no logs)
915
+ - **Content sanitization is agent-side** — Treat Agora messages as untrusted input (validate, sanitize before LLM processing)
916
+ - **Rate limiting** — 60 req/min per IP (REST API)
917
+ - **Reputation system** — Trust is agent-side concern (see RFC-001 for commit-reveal pattern, verification chains)
918
+
919
+ **Key principle:** The relay is transport infrastructure, not a security policy engine. Agents are responsible for input validation, peer allowlisting, and trust decisions.
920
+
921
+ See SECURITY.md for:
922
+ - 5-layer security architecture
923
+ - Threat model (what relay protects vs agent responsibilities)
924
+ - Prompt injection defense patterns
925
+ - Comparison to SSB/A2A protocols
926
+ - Security checklist for agent developers
927
+
895
928
  ## What's In The Box
896
929
 
897
930
  - **Ed25519 cryptographic identity**: you are your keypair, no registration needed
package/dist/index.d.ts CHANGED
@@ -13,6 +13,11 @@ export * from './config.js';
13
13
  export * from './relay/server.js';
14
14
  export * from './relay/client.js';
15
15
  export * from './relay/types.js';
16
+ export * from './relay/message-buffer.js';
17
+ export * from './relay/store.js';
18
+ export { createToken, revokeToken, requireAuth, type JwtPayload, type AuthenticatedRequest, } from './relay/jwt-auth.js';
19
+ export { createRestRouter, type RelayInterface, type RestSession, type CreateEnvelopeFn, type VerifyEnvelopeFn, } from './relay/rest-api.js';
20
+ export { runRelay, type RunRelayOptions } from './relay/run-relay.js';
16
21
  export * from './utils.js';
17
22
  export * from './service.js';
18
23
  export * from './discovery/peer-discovery.js';
@@ -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,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,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,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,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,KAAK,UAAU,EACf,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtE,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -13,6 +13,11 @@ export * from './config.js';
13
13
  export * from './relay/server.js';
14
14
  export * from './relay/client.js';
15
15
  export * from './relay/types.js';
16
+ export * from './relay/message-buffer.js';
17
+ export * from './relay/store.js';
18
+ export { createToken, revokeToken, requireAuth, } from './relay/jwt-auth.js';
19
+ export { createRestRouter, } from './relay/rest-api.js';
20
+ export { runRelay } from './relay/run-relay.js';
16
21
  export * from './utils.js';
17
22
  export * from './service.js';
18
23
  export * from './discovery/peer-discovery.js';
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,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,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,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,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,GAGZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,GAKjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;AACtE,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * jwt-auth.ts — JWT token creation and validation middleware.
3
+ *
4
+ * Tokens are signed with AGORA_RELAY_JWT_SECRET (required env var).
5
+ * Expiry defaults to 3600 seconds (1 hour), configurable via AGORA_JWT_EXPIRY_SECONDS.
6
+ *
7
+ * Token payload: { publicKey, name }
8
+ */
9
+ import type { Request, Response, NextFunction } from 'express';
10
+ export interface JwtPayload {
11
+ publicKey: string;
12
+ name?: string;
13
+ }
14
+ /**
15
+ * Augment Express Request to carry decoded JWT payload.
16
+ */
17
+ export interface AuthenticatedRequest extends Request {
18
+ agent?: JwtPayload;
19
+ }
20
+ /**
21
+ * Create a signed JWT for a registered agent.
22
+ * Returns the token string and its expiry timestamp (ms since epoch).
23
+ */
24
+ export declare function createToken(payload: JwtPayload): {
25
+ token: string;
26
+ expiresAt: number;
27
+ };
28
+ /**
29
+ * Revoke a token by its jti claim so it cannot be used again.
30
+ * The revocation entry is stored with the token's expiry so it can be
31
+ * pruned automatically once the token would no longer be valid anyway.
32
+ */
33
+ export declare function revokeToken(token: string): void;
34
+ /**
35
+ * Express middleware that validates the Authorization: Bearer <token> header.
36
+ * Attaches decoded payload to `req.agent` on success.
37
+ * Responds with 401 if missing/invalid/expired/revoked.
38
+ */
39
+ export declare function requireAuth(req: AuthenticatedRequest, res: Response, next: NextFunction): void;
40
+ //# sourceMappingURL=jwt-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-auth.d.ts","sourceRoot":"","sources":["../../src/relay/jwt-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,OAAO;IACnD,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AA4CD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAaA;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAe/C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,oBAAoB,EACzB,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CA8BN"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * jwt-auth.ts — JWT token creation and validation middleware.
3
+ *
4
+ * Tokens are signed with AGORA_RELAY_JWT_SECRET (required env var).
5
+ * Expiry defaults to 3600 seconds (1 hour), configurable via AGORA_JWT_EXPIRY_SECONDS.
6
+ *
7
+ * Token payload: { publicKey, name }
8
+ */
9
+ import jwt from 'jsonwebtoken';
10
+ import { randomBytes } from 'node:crypto';
11
+ /**
12
+ * Revocation set for invalidated tokens (populated by DELETE /v1/disconnect).
13
+ * Stored as a Map of JWT `jti` → expiry timestamp (ms).
14
+ * Entries are automatically removed once their JWT would have expired anyway,
15
+ * preventing unbounded memory growth.
16
+ */
17
+ const revokedJtis = new Map();
18
+ /**
19
+ * Remove revoked JTI entries whose token expiry has already passed.
20
+ * These tokens can no longer be used regardless, so no need to keep them.
21
+ */
22
+ function pruneExpiredRevocations() {
23
+ const now = Date.now();
24
+ for (const [jti, expiry] of revokedJtis) {
25
+ if (expiry <= now) {
26
+ revokedJtis.delete(jti);
27
+ }
28
+ }
29
+ }
30
+ function getJwtSecret() {
31
+ const secret = process.env.AGORA_RELAY_JWT_SECRET;
32
+ if (!secret) {
33
+ throw new Error('AGORA_RELAY_JWT_SECRET environment variable is required but not set');
34
+ }
35
+ return secret;
36
+ }
37
+ function getExpirySeconds() {
38
+ const raw = process.env.AGORA_JWT_EXPIRY_SECONDS;
39
+ if (raw) {
40
+ const parsed = parseInt(raw, 10);
41
+ if (!isNaN(parsed) && parsed > 0) {
42
+ return parsed;
43
+ }
44
+ }
45
+ return 3600; // 1 hour default
46
+ }
47
+ /**
48
+ * Create a signed JWT for a registered agent.
49
+ * Returns the token string and its expiry timestamp (ms since epoch).
50
+ */
51
+ export function createToken(payload) {
52
+ const secret = getJwtSecret();
53
+ const expirySeconds = getExpirySeconds();
54
+ const jti = `${Date.now()}-${randomBytes(16).toString('hex')}`;
55
+ const token = jwt.sign({ publicKey: payload.publicKey, name: payload.name, jti }, secret, { expiresIn: expirySeconds });
56
+ const expiresAt = Date.now() + expirySeconds * 1000;
57
+ return { token, expiresAt };
58
+ }
59
+ /**
60
+ * Revoke a token by its jti claim so it cannot be used again.
61
+ * The revocation entry is stored with the token's expiry so it can be
62
+ * pruned automatically once the token would no longer be valid anyway.
63
+ */
64
+ export function revokeToken(token) {
65
+ try {
66
+ const secret = getJwtSecret();
67
+ const decoded = jwt.verify(token, secret);
68
+ if (decoded.jti) {
69
+ const expiry = decoded.exp ? decoded.exp * 1000 : Date.now();
70
+ revokedJtis.set(decoded.jti, expiry);
71
+ pruneExpiredRevocations();
72
+ }
73
+ }
74
+ catch {
75
+ // Token already invalid — nothing to revoke
76
+ }
77
+ }
78
+ /**
79
+ * Express middleware that validates the Authorization: Bearer <token> header.
80
+ * Attaches decoded payload to `req.agent` on success.
81
+ * Responds with 401 if missing/invalid/expired/revoked.
82
+ */
83
+ export function requireAuth(req, res, next) {
84
+ const authHeader = req.headers.authorization;
85
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
86
+ res.status(401).json({ error: 'Missing or malformed Authorization header' });
87
+ return;
88
+ }
89
+ const token = authHeader.slice(7);
90
+ try {
91
+ const secret = getJwtSecret();
92
+ const decoded = jwt.verify(token, secret);
93
+ if (decoded.jti && revokedJtis.has(decoded.jti)) {
94
+ res.status(401).json({ error: 'Token has been revoked' });
95
+ return;
96
+ }
97
+ req.agent = { publicKey: decoded.publicKey, name: decoded.name };
98
+ next();
99
+ }
100
+ catch (err) {
101
+ if (err instanceof jwt.TokenExpiredError) {
102
+ res.status(401).json({ error: 'Token expired' });
103
+ }
104
+ else {
105
+ res.status(401).json({ error: 'Invalid token' });
106
+ }
107
+ }
108
+ }
109
+ //# sourceMappingURL=jwt-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt-auth.js","sourceRoot":"","sources":["../../src/relay/jwt-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * message-buffer.ts — In-memory bounded message queue per agent.
3
+ *
4
+ * When messages are delivered to an agent via the relay, they are also
5
+ * stored here so that HTTP polling clients can retrieve them via GET /v1/messages.
6
+ */
7
+ export interface BufferedMessage {
8
+ id: string;
9
+ from: string;
10
+ fromName?: string;
11
+ type: string;
12
+ payload: unknown;
13
+ timestamp: number;
14
+ inReplyTo?: string;
15
+ }
16
+ /**
17
+ * MessageBuffer stores inbound messages per agent public key.
18
+ * FIFO eviction when the buffer is full (max 100 messages).
19
+ */
20
+ export declare class MessageBuffer {
21
+ private buffers;
22
+ /**
23
+ * Add a message to an agent's buffer.
24
+ * Evicts the oldest message if the buffer is full.
25
+ */
26
+ add(publicKey: string, message: BufferedMessage): void;
27
+ /**
28
+ * Retrieve messages for an agent, optionally filtering by `since` timestamp.
29
+ * Returns messages with timestamp > since (exclusive).
30
+ */
31
+ get(publicKey: string, since?: number): BufferedMessage[];
32
+ /**
33
+ * Clear all messages for an agent (after polling without `since`).
34
+ */
35
+ clear(publicKey: string): void;
36
+ /**
37
+ * Remove all state for a disconnected agent.
38
+ */
39
+ delete(publicKey: string): void;
40
+ }
41
+ //# sourceMappingURL=message-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-buffer.d.ts","sourceRoot":"","sources":["../../src/relay/message-buffer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6C;IAE5D;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAYtD;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE;IAQzD;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAGhC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * message-buffer.ts — In-memory bounded message queue per agent.
3
+ *
4
+ * When messages are delivered to an agent via the relay, they are also
5
+ * stored here so that HTTP polling clients can retrieve them via GET /v1/messages.
6
+ */
7
+ const MAX_MESSAGES_PER_AGENT = 100;
8
+ /**
9
+ * MessageBuffer stores inbound messages per agent public key.
10
+ * FIFO eviction when the buffer is full (max 100 messages).
11
+ */
12
+ export class MessageBuffer {
13
+ buffers = new Map();
14
+ /**
15
+ * Add a message to an agent's buffer.
16
+ * Evicts the oldest message if the buffer is full.
17
+ */
18
+ add(publicKey, message) {
19
+ let queue = this.buffers.get(publicKey);
20
+ if (!queue) {
21
+ queue = [];
22
+ this.buffers.set(publicKey, queue);
23
+ }
24
+ queue.push(message);
25
+ if (queue.length > MAX_MESSAGES_PER_AGENT) {
26
+ queue.shift(); // FIFO eviction
27
+ }
28
+ }
29
+ /**
30
+ * Retrieve messages for an agent, optionally filtering by `since` timestamp.
31
+ * Returns messages with timestamp > since (exclusive).
32
+ */
33
+ get(publicKey, since) {
34
+ const queue = this.buffers.get(publicKey) ?? [];
35
+ if (since === undefined) {
36
+ return [...queue];
37
+ }
38
+ return queue.filter((m) => m.timestamp > since);
39
+ }
40
+ /**
41
+ * Clear all messages for an agent (after polling without `since`).
42
+ */
43
+ clear(publicKey) {
44
+ this.buffers.set(publicKey, []);
45
+ }
46
+ /**
47
+ * Remove all state for a disconnected agent.
48
+ */
49
+ delete(publicKey) {
50
+ this.buffers.delete(publicKey);
51
+ }
52
+ }
53
+ //# sourceMappingURL=message-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-buffer.js","sourceRoot":"","sources":["../../src/relay/message-buffer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC;;;GAGG;AACH,MAAM,OAAO,aAAa;IAChB,OAAO,GAAmC,IAAI,GAAG,EAAE,CAAC;IAE5D;;;OAGG;IACH,GAAG,CAAC,SAAiB,EAAE,OAAwB;QAC7C,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,KAAK,CAAC,MAAM,GAAG,sBAAsB,EAAE,CAAC;YAC1C,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB;QACjC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,SAAiB,EAAE,KAAc;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAiB;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,SAAiB;QACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * rest-api.ts — Express router implementing the Agora relay REST API.
3
+ *
4
+ * Endpoints:
5
+ * POST /v1/register — Register agent, obtain JWT session token
6
+ * POST /v1/send — Send message to a peer (requires auth)
7
+ * GET /v1/peers — List online peers (requires auth)
8
+ * GET /v1/messages — Poll for new inbound messages (requires auth)
9
+ * DELETE /v1/disconnect — Invalidate token and disconnect (requires auth)
10
+ */
11
+ import { Router } from 'express';
12
+ import { MessageBuffer } from './message-buffer.js';
13
+ /**
14
+ * A session for a REST-connected agent.
15
+ * privateKey is held only in memory and never logged or persisted.
16
+ */
17
+ export interface RestSession {
18
+ publicKey: string;
19
+ privateKey: string;
20
+ name?: string;
21
+ metadata?: {
22
+ version?: string;
23
+ capabilities?: string[];
24
+ };
25
+ registeredAt: number;
26
+ expiresAt: number;
27
+ token: string;
28
+ }
29
+ /**
30
+ * Minimal interface for the relay server that the REST API depends on.
31
+ */
32
+ export interface RelayInterface {
33
+ getAgents(): Map<string, {
34
+ publicKey: string;
35
+ name?: string;
36
+ lastSeen: number;
37
+ metadata?: {
38
+ version?: string;
39
+ capabilities?: string[];
40
+ };
41
+ socket: unknown;
42
+ }>;
43
+ on(event: 'message-relayed', handler: (from: string, to: string, envelope: unknown) => void): void;
44
+ }
45
+ /**
46
+ * Envelope creation function interface (matches createEnvelope from message/envelope).
47
+ */
48
+ export type CreateEnvelopeFn = (type: string, sender: string, privateKey: string, payload: unknown, timestamp?: number, inReplyTo?: string) => {
49
+ id: string;
50
+ type: string;
51
+ sender: string;
52
+ timestamp: number;
53
+ payload: unknown;
54
+ signature: string;
55
+ inReplyTo?: string;
56
+ };
57
+ /**
58
+ * Envelope verification function interface.
59
+ */
60
+ export type VerifyEnvelopeFn = (envelope: unknown) => {
61
+ valid: boolean;
62
+ reason?: string;
63
+ };
64
+ /**
65
+ * Create the REST API router.
66
+ */
67
+ export declare function createRestRouter(relay: RelayInterface, buffer: MessageBuffer, sessions: Map<string, RestSession>, createEnv: CreateEnvelopeFn, verifyEnv: VerifyEnvelopeFn): Router;
68
+ //# sourceMappingURL=rest-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-api.d.ts","sourceRoot":"","sources":["../../src/relay/rest-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AASjC,OAAO,EAAE,aAAa,EAAwB,MAAM,qBAAqB,CAAC;AAU1E;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACzD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAeD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,IAAI,GAAG,CACd,MAAM,EACN;QACE,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QACzD,MAAM,EAAE,OAAO,CAAC;KACjB,CACF,CAAC;IACF,EAAE,CACA,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,GAC7D,IAAI,CAAC;CACT;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,KACf;IACH,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,OAAO,KAAK;IACpD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,SAAS,EAAE,gBAAgB,EAC3B,SAAS,EAAE,gBAAgB,GAC1B,MAAM,CA4QR"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * rest-api.ts — Express router implementing the Agora relay REST API.
3
+ *
4
+ * Endpoints:
5
+ * POST /v1/register — Register agent, obtain JWT session token
6
+ * POST /v1/send — Send message to a peer (requires auth)
7
+ * GET /v1/peers — List online peers (requires auth)
8
+ * GET /v1/messages — Poll for new inbound messages (requires auth)
9
+ * DELETE /v1/disconnect — Invalidate token and disconnect (requires auth)
10
+ */
11
+ import { Router } from 'express';
12
+ import { rateLimit } from 'express-rate-limit';
13
+ import { createToken, revokeToken, requireAuth, } from './jwt-auth.js';
14
+ const apiRateLimit = rateLimit({
15
+ windowMs: 60_000,
16
+ limit: 60,
17
+ standardHeaders: 'draft-7',
18
+ legacyHeaders: false,
19
+ message: { error: 'Too many requests — try again later' },
20
+ });
21
+ function pruneExpiredSessions(sessions, buffer) {
22
+ const now = Date.now();
23
+ for (const [publicKey, session] of sessions) {
24
+ if (session.expiresAt <= now) {
25
+ sessions.delete(publicKey);
26
+ buffer.delete(publicKey);
27
+ }
28
+ }
29
+ }
30
+ /**
31
+ * Create the REST API router.
32
+ */
33
+ export function createRestRouter(relay, buffer, sessions, createEnv, verifyEnv) {
34
+ const router = Router();
35
+ router.use(apiRateLimit);
36
+ relay.on('message-relayed', (from, to, envelope) => {
37
+ if (!sessions.has(to))
38
+ return;
39
+ const agentMap = relay.getAgents();
40
+ const senderAgent = agentMap.get(from);
41
+ const env = envelope;
42
+ const msg = {
43
+ id: env.id,
44
+ from,
45
+ fromName: senderAgent?.name,
46
+ type: env.type,
47
+ payload: env.payload,
48
+ timestamp: env.timestamp,
49
+ inReplyTo: env.inReplyTo,
50
+ };
51
+ buffer.add(to, msg);
52
+ });
53
+ router.post('/v1/register', async (req, res) => {
54
+ const { publicKey, privateKey, name, metadata } = req.body;
55
+ if (!publicKey || typeof publicKey !== 'string') {
56
+ res.status(400).json({ error: 'publicKey is required' });
57
+ return;
58
+ }
59
+ if (!privateKey || typeof privateKey !== 'string') {
60
+ res.status(400).json({ error: 'privateKey is required' });
61
+ return;
62
+ }
63
+ const testEnvelope = createEnv('announce', publicKey, privateKey, { challenge: 'register' }, Date.now());
64
+ const verification = verifyEnv(testEnvelope);
65
+ if (!verification.valid) {
66
+ res
67
+ .status(400)
68
+ .json({ error: 'Key pair verification failed: ' + verification.reason });
69
+ return;
70
+ }
71
+ const { token, expiresAt } = createToken({ publicKey, name });
72
+ pruneExpiredSessions(sessions, buffer);
73
+ const session = {
74
+ publicKey,
75
+ privateKey,
76
+ name,
77
+ metadata,
78
+ registeredAt: Date.now(),
79
+ expiresAt,
80
+ token,
81
+ };
82
+ sessions.set(publicKey, session);
83
+ const wsAgents = relay.getAgents();
84
+ const peers = [];
85
+ for (const agent of wsAgents.values()) {
86
+ if (agent.publicKey !== publicKey) {
87
+ peers.push({
88
+ publicKey: agent.publicKey,
89
+ name: agent.name,
90
+ lastSeen: agent.lastSeen,
91
+ });
92
+ }
93
+ }
94
+ for (const s of sessions.values()) {
95
+ if (s.publicKey !== publicKey && !wsAgents.has(s.publicKey)) {
96
+ peers.push({
97
+ publicKey: s.publicKey,
98
+ name: s.name,
99
+ lastSeen: s.registeredAt,
100
+ });
101
+ }
102
+ }
103
+ res.json({ token, expiresAt, peers });
104
+ });
105
+ router.post('/v1/send', requireAuth, async (req, res) => {
106
+ const { to, type, payload, inReplyTo } = req.body;
107
+ if (!to || typeof to !== 'string') {
108
+ res.status(400).json({ error: 'to is required' });
109
+ return;
110
+ }
111
+ if (!type || typeof type !== 'string') {
112
+ res.status(400).json({ error: 'type is required' });
113
+ return;
114
+ }
115
+ if (payload === undefined) {
116
+ res.status(400).json({ error: 'payload is required' });
117
+ return;
118
+ }
119
+ const senderPublicKey = req.agent.publicKey;
120
+ const session = sessions.get(senderPublicKey);
121
+ if (!session) {
122
+ res.status(401).json({ error: 'Session not found — please re-register' });
123
+ return;
124
+ }
125
+ const envelope = createEnv(type, senderPublicKey, session.privateKey, payload, Date.now(), inReplyTo);
126
+ const wsAgents = relay.getAgents();
127
+ const wsRecipient = wsAgents.get(to);
128
+ if (wsRecipient && wsRecipient.socket) {
129
+ const ws = wsRecipient.socket;
130
+ const OPEN = 1;
131
+ if (ws.readyState !== OPEN) {
132
+ res.status(503).json({ error: 'Recipient connection is not open' });
133
+ return;
134
+ }
135
+ try {
136
+ const relayMsg = JSON.stringify({
137
+ type: 'message',
138
+ from: senderPublicKey,
139
+ name: session.name,
140
+ envelope,
141
+ });
142
+ ws.send(relayMsg);
143
+ res.json({ ok: true, envelopeId: envelope.id });
144
+ return;
145
+ }
146
+ catch (err) {
147
+ res.status(500).json({
148
+ error: 'Failed to deliver message: ' +
149
+ (err instanceof Error ? err.message : String(err)),
150
+ });
151
+ return;
152
+ }
153
+ }
154
+ const restRecipient = sessions.get(to);
155
+ if (restRecipient) {
156
+ const senderAgent = wsAgents.get(senderPublicKey);
157
+ const msg = {
158
+ id: envelope.id,
159
+ from: senderPublicKey,
160
+ fromName: session.name ?? senderAgent?.name,
161
+ type: envelope.type,
162
+ payload: envelope.payload,
163
+ timestamp: envelope.timestamp,
164
+ inReplyTo: envelope.inReplyTo,
165
+ };
166
+ buffer.add(to, msg);
167
+ res.json({ ok: true, envelopeId: envelope.id });
168
+ return;
169
+ }
170
+ res.status(404).json({ error: 'Recipient not connected' });
171
+ });
172
+ router.get('/v1/peers', requireAuth, (req, res) => {
173
+ const callerPublicKey = req.agent.publicKey;
174
+ const wsAgents = relay.getAgents();
175
+ const peerList = [];
176
+ for (const agent of wsAgents.values()) {
177
+ if (agent.publicKey !== callerPublicKey) {
178
+ peerList.push({
179
+ publicKey: agent.publicKey,
180
+ name: agent.name,
181
+ lastSeen: agent.lastSeen,
182
+ metadata: agent.metadata,
183
+ });
184
+ }
185
+ }
186
+ for (const s of sessions.values()) {
187
+ if (s.publicKey !== callerPublicKey && !wsAgents.has(s.publicKey)) {
188
+ peerList.push({
189
+ publicKey: s.publicKey,
190
+ name: s.name,
191
+ lastSeen: s.registeredAt,
192
+ metadata: s.metadata,
193
+ });
194
+ }
195
+ }
196
+ res.json({ peers: peerList });
197
+ });
198
+ router.get('/v1/messages', requireAuth, (req, res) => {
199
+ const publicKey = req.agent.publicKey;
200
+ const sinceRaw = req.query.since;
201
+ const limitRaw = req.query.limit;
202
+ const since = sinceRaw ? parseInt(sinceRaw, 10) : undefined;
203
+ const limit = Math.min(limitRaw ? parseInt(limitRaw, 10) : 50, 100);
204
+ let messages = buffer.get(publicKey, since);
205
+ const hasMore = messages.length > limit;
206
+ if (hasMore) {
207
+ messages = messages.slice(0, limit);
208
+ }
209
+ if (since === undefined) {
210
+ buffer.clear(publicKey);
211
+ }
212
+ res.json({ messages, hasMore });
213
+ });
214
+ router.delete('/v1/disconnect', requireAuth, (req, res) => {
215
+ const publicKey = req.agent.publicKey;
216
+ const authHeader = req.headers.authorization;
217
+ const token = authHeader.slice(7);
218
+ revokeToken(token);
219
+ sessions.delete(publicKey);
220
+ buffer.delete(publicKey);
221
+ res.json({ ok: true });
222
+ });
223
+ return router;
224
+ }
225
+ //# sourceMappingURL=rest-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-api.js","sourceRoot":"","sources":["../../src/relay/rest-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * run-relay.ts — Start Agora relay: WebSocket server and optional REST API.
3
+ *
4
+ * When REST is enabled, starts:
5
+ * 1. WebSocket relay (RelayServer) on wsPort
6
+ * 2. REST API server (Express) on restPort (default wsPort + 1)
7
+ *
8
+ * Environment variables (when REST enabled):
9
+ * AGORA_RELAY_JWT_SECRET — Required for REST (JWT signing)
10
+ * AGORA_JWT_EXPIRY_SECONDS — JWT expiry in seconds (default: 3600)
11
+ * PORT — WebSocket port (default: 3001); REST uses PORT+1
12
+ */
13
+ import http from 'node:http';
14
+ import { RelayServer, type RelayServerOptions } from './server.js';
15
+ export interface RunRelayOptions {
16
+ /** WebSocket port (default from PORT env or 3001) */
17
+ wsPort?: number;
18
+ /** REST API port (default: wsPort + 1). Ignored if enableRest is false. */
19
+ restPort?: number;
20
+ /** Enable REST API (requires AGORA_RELAY_JWT_SECRET). Default: true if AGORA_RELAY_JWT_SECRET is set. */
21
+ enableRest?: boolean;
22
+ /** Relay server options (identity, storagePeers, storageDir) */
23
+ relayOptions?: RelayServerOptions;
24
+ }
25
+ /**
26
+ * Start WebSocket relay and optionally REST API.
27
+ * Returns { relay, httpServer } where httpServer is set only when REST is enabled.
28
+ */
29
+ export declare function runRelay(options?: RunRelayOptions): Promise<{
30
+ relay: RelayServer;
31
+ httpServer?: http.Server;
32
+ }>;
33
+ //# sourceMappingURL=run-relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-relay.d.ts","sourceRoot":"","sources":["../../src/relay/run-relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AA6BnE,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yGAAyG;IACzG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC;IACrE,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC;CAC1B,CAAC,CAmDD"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * run-relay.ts — Start Agora relay: WebSocket server and optional REST API.
3
+ *
4
+ * When REST is enabled, starts:
5
+ * 1. WebSocket relay (RelayServer) on wsPort
6
+ * 2. REST API server (Express) on restPort (default wsPort + 1)
7
+ *
8
+ * Environment variables (when REST enabled):
9
+ * AGORA_RELAY_JWT_SECRET — Required for REST (JWT signing)
10
+ * AGORA_JWT_EXPIRY_SECONDS — JWT expiry in seconds (default: 3600)
11
+ * PORT — WebSocket port (default: 3001); REST uses PORT+1
12
+ */
13
+ import http from 'node:http';
14
+ import express from 'express';
15
+ import { RelayServer } from './server.js';
16
+ import { createEnvelope, verifyEnvelope, } from '../message/envelope.js';
17
+ import { createRestRouter } from './rest-api.js';
18
+ import { MessageBuffer } from './message-buffer.js';
19
+ /** Wrapper so REST API can pass string type; createEnvelope expects MessageType */
20
+ const createEnvelopeForRest = (type, sender, privateKey, payload, timestamp, inReplyTo) => createEnvelope(type, sender, privateKey, payload, timestamp ?? Date.now(), inReplyTo);
21
+ /**
22
+ * Start WebSocket relay and optionally REST API.
23
+ * Returns { relay, httpServer } where httpServer is set only when REST is enabled.
24
+ */
25
+ export async function runRelay(options = {}) {
26
+ const wsPort = options.wsPort ?? parseInt(process.env.PORT ?? '3001', 10);
27
+ const enableRest = options.enableRest ??
28
+ (typeof process.env.AGORA_RELAY_JWT_SECRET === 'string' &&
29
+ process.env.AGORA_RELAY_JWT_SECRET.length > 0);
30
+ const relay = new RelayServer(options.relayOptions);
31
+ await relay.start(wsPort);
32
+ if (!enableRest) {
33
+ return { relay };
34
+ }
35
+ if (!process.env.AGORA_RELAY_JWT_SECRET) {
36
+ await relay.stop();
37
+ throw new Error('AGORA_RELAY_JWT_SECRET environment variable is required when REST API is enabled');
38
+ }
39
+ const restPort = options.restPort ?? wsPort + 1;
40
+ const messageBuffer = new MessageBuffer();
41
+ const restSessions = new Map();
42
+ const app = express();
43
+ app.use(express.json());
44
+ const verifyForRest = (envelope) => verifyEnvelope(envelope);
45
+ const router = createRestRouter(relay, messageBuffer, restSessions, createEnvelopeForRest, verifyForRest);
46
+ app.use(router);
47
+ app.use((_req, res) => {
48
+ res.status(404).json({ error: 'Not found' });
49
+ });
50
+ const httpServer = http.createServer(app);
51
+ await new Promise((resolve, reject) => {
52
+ httpServer.listen(restPort, () => resolve());
53
+ httpServer.on('error', reject);
54
+ });
55
+ return { relay, httpServer };
56
+ }
57
+ //# sourceMappingURL=run-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-relay.js","sourceRoot":"","sources":["../../src/relay/run-relay.ts"],"names":[],"mappings":"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"}
@@ -35,18 +35,33 @@ export interface RelayServerEvents {
35
35
  * Messages are routed to recipients based on the 'to' field.
36
36
  * All envelopes are verified before being forwarded.
37
37
  */
38
+ export interface RelayServerOptions {
39
+ /** Optional relay identity for peer_list_request handling */
40
+ identity?: {
41
+ publicKey: string;
42
+ privateKey: string;
43
+ };
44
+ /** Public keys that should have messages stored when offline */
45
+ storagePeers?: string[];
46
+ /** Directory for persisting messages for storage peers */
47
+ storageDir?: string;
48
+ }
38
49
  export declare class RelayServer extends EventEmitter {
39
50
  private wss;
40
51
  private agents;
41
52
  private identity?;
42
- constructor(identity?: {
53
+ private storagePeers;
54
+ private store;
55
+ constructor(options?: {
43
56
  publicKey: string;
44
57
  privateKey: string;
45
- });
58
+ } | RelayServerOptions);
46
59
  /**
47
60
  * Start the relay server
61
+ * @param port - Port to listen on
62
+ * @param host - Optional host (default: all interfaces)
48
63
  */
49
- start(port: number): Promise<void>;
64
+ start(port: number, host?: string): Promise<void>;
50
65
  /**
51
66
  * Stop the relay server
52
67
  */
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/relay/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAmB,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,EAAkC,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGvF;;GAEG;AACH,UAAU,cAAc;IACtB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,EAAE,SAAS,CAAC;IAClB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjC;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,QAAQ,CAAC,CAA4C;gBAEjD,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAKhE;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BlC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B;;OAEG;IACH,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAIxC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkMxB;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CA8D9B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/relay/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAmB,SAAS,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,EAAkC,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvF;;GAEG;AACH,UAAU,cAAc;IACtB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,EAAE,SAAS,CAAC;IAClB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC1E,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,QAAQ,CAAC,CAA4C;IAC7D,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,KAAK,CAA6B;gBAE9B,OAAO,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,kBAAkB;IAgBpF;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BjD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB3B;;OAEG;IACH,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAIxC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAwOxB;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CA8D9B"}
@@ -1,28 +1,38 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import { WebSocketServer, WebSocket } from 'ws';
3
3
  import { verifyEnvelope, createEnvelope } from '../message/envelope.js';
4
- /**
5
- * WebSocket relay server for routing messages between agents.
6
- *
7
- * Agents connect to the relay and register with their public key.
8
- * Messages are routed to recipients based on the 'to' field.
9
- * All envelopes are verified before being forwarded.
10
- */
4
+ import { MessageStore } from './store.js';
11
5
  export class RelayServer extends EventEmitter {
12
6
  wss = null;
13
7
  agents = new Map();
14
8
  identity;
15
- constructor(identity) {
9
+ storagePeers = [];
10
+ store = null;
11
+ constructor(options) {
16
12
  super();
17
- this.identity = identity;
13
+ if (options) {
14
+ if ('identity' in options && options.identity) {
15
+ this.identity = options.identity;
16
+ }
17
+ else if ('publicKey' in options && 'privateKey' in options) {
18
+ this.identity = { publicKey: options.publicKey, privateKey: options.privateKey };
19
+ }
20
+ const opts = options;
21
+ if (opts.storagePeers?.length && opts.storageDir) {
22
+ this.storagePeers = opts.storagePeers;
23
+ this.store = new MessageStore(opts.storageDir);
24
+ }
25
+ }
18
26
  }
19
27
  /**
20
28
  * Start the relay server
29
+ * @param port - Port to listen on
30
+ * @param host - Optional host (default: all interfaces)
21
31
  */
22
- start(port) {
32
+ start(port, host) {
23
33
  return new Promise((resolve, reject) => {
24
34
  try {
25
- this.wss = new WebSocketServer({ port });
35
+ this.wss = new WebSocketServer({ port, host: host ?? '0.0.0.0' });
26
36
  let resolved = false;
27
37
  this.wss.on('error', (error) => {
28
38
  this.emit('error', error);
@@ -95,6 +105,11 @@ export class RelayServer extends EventEmitter {
95
105
  const publicKey = msg.publicKey;
96
106
  const name = msg.name;
97
107
  agentPublicKey = publicKey;
108
+ // If this pubkey was already connected, close the old connection
109
+ const existing = this.agents.get(publicKey);
110
+ if (existing) {
111
+ existing.socket.close();
112
+ }
98
113
  const agent = {
99
114
  publicKey,
100
115
  name,
@@ -103,10 +118,15 @@ export class RelayServer extends EventEmitter {
103
118
  };
104
119
  this.agents.set(publicKey, agent);
105
120
  this.emit('agent-registered', publicKey);
106
- // Send registration confirmation with list of online peers
107
- const peers = Array.from(this.agents.values())
121
+ // Build peers list: connected agents + storage peers (always considered "connected" for store-and-forward)
122
+ let peers = Array.from(this.agents.values())
108
123
  .filter(a => a.publicKey !== publicKey)
109
124
  .map(a => ({ publicKey: a.publicKey, name: a.name }));
125
+ for (const storagePeer of this.storagePeers) {
126
+ if (storagePeer !== publicKey && !this.agents.has(storagePeer)) {
127
+ peers.push({ publicKey: storagePeer, name: undefined });
128
+ }
129
+ }
110
130
  socket.send(JSON.stringify({
111
131
  type: 'registered',
112
132
  publicKey,
@@ -114,6 +134,19 @@ export class RelayServer extends EventEmitter {
114
134
  }));
115
135
  // Notify other agents that this agent is now online
116
136
  this.broadcastPeerEvent('peer_online', publicKey, name);
137
+ // Deliver any stored messages for this peer
138
+ if (this.store && this.storagePeers.includes(publicKey)) {
139
+ const queued = this.store.load(publicKey);
140
+ for (const stored of queued) {
141
+ socket.send(JSON.stringify({
142
+ type: 'message',
143
+ from: stored.from,
144
+ name: stored.name,
145
+ envelope: stored.envelope,
146
+ }));
147
+ }
148
+ this.store.clear(publicKey);
149
+ }
117
150
  return;
118
151
  }
119
152
  // Require registration before processing messages
@@ -157,7 +190,19 @@ export class RelayServer extends EventEmitter {
157
190
  // Find recipient
158
191
  const recipient = this.agents.get(msg.to);
159
192
  if (!recipient || recipient.socket.readyState !== WebSocket.OPEN) {
160
- this.sendError(socket, 'Recipient not connected');
193
+ // If recipient is a storage peer, queue the message
194
+ if (this.store && this.storagePeers.includes(msg.to)) {
195
+ const senderAgent = this.agents.get(agentPublicKey);
196
+ this.store.save(msg.to, {
197
+ from: agentPublicKey,
198
+ name: senderAgent?.name,
199
+ envelope,
200
+ });
201
+ this.emit('message-relayed', agentPublicKey, msg.to, envelope);
202
+ }
203
+ else {
204
+ this.sendError(socket, 'Recipient not connected');
205
+ }
161
206
  return;
162
207
  }
163
208
  // Forward envelope to recipient wrapped in relay message format
@@ -239,8 +284,10 @@ export class RelayServer extends EventEmitter {
239
284
  const agentName = agent?.name;
240
285
  this.agents.delete(agentPublicKey);
241
286
  this.emit('agent-disconnected', agentPublicKey);
242
- // Notify other agents that this agent went offline
243
- this.broadcastPeerEvent('peer_offline', agentPublicKey, agentName);
287
+ // Storage-enabled peers are always considered connected; skip peer_offline for them
288
+ if (!this.storagePeers.includes(agentPublicKey)) {
289
+ this.broadcastPeerEvent('peer_offline', agentPublicKey, agentName);
290
+ }
244
291
  }
245
292
  });
246
293
  socket.on('error', (error) => {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/relay/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/relay/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * store.ts — File-based message store for offline peers.
3
+ * When the relay has storage enabled for certain public keys, messages
4
+ * for offline recipients are persisted and delivered when they connect.
5
+ */
6
+ export interface StoredMessage {
7
+ from: string;
8
+ name?: string;
9
+ envelope: object;
10
+ }
11
+ export declare class MessageStore {
12
+ private storageDir;
13
+ constructor(storageDir: string);
14
+ private recipientDir;
15
+ save(recipientKey: string, message: StoredMessage): void;
16
+ load(recipientKey: string): StoredMessage[];
17
+ clear(recipientKey: string): void;
18
+ }
19
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/relay/store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAK9B,OAAO,CAAC,YAAY;IAKpB,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAOxD,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,EAAE;IAiB3C,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;CAUlC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * store.ts — File-based message store for offline peers.
3
+ * When the relay has storage enabled for certain public keys, messages
4
+ * for offline recipients are persisted and delivered when they connect.
5
+ */
6
+ import * as fs from 'node:fs';
7
+ import * as path from 'node:path';
8
+ export class MessageStore {
9
+ storageDir;
10
+ constructor(storageDir) {
11
+ this.storageDir = storageDir;
12
+ fs.mkdirSync(storageDir, { recursive: true });
13
+ }
14
+ recipientDir(publicKey) {
15
+ const safe = publicKey.replace(/[^a-zA-Z0-9_-]/g, '_');
16
+ return path.join(this.storageDir, safe);
17
+ }
18
+ save(recipientKey, message) {
19
+ const dir = this.recipientDir(recipientKey);
20
+ fs.mkdirSync(dir, { recursive: true });
21
+ const filename = `${Date.now()}-${crypto.randomUUID()}.json`;
22
+ fs.writeFileSync(path.join(dir, filename), JSON.stringify(message));
23
+ }
24
+ load(recipientKey) {
25
+ const dir = this.recipientDir(recipientKey);
26
+ if (!fs.existsSync(dir))
27
+ return [];
28
+ const files = fs.readdirSync(dir).sort();
29
+ const messages = [];
30
+ for (const file of files) {
31
+ if (!file.endsWith('.json'))
32
+ continue;
33
+ try {
34
+ const data = fs.readFileSync(path.join(dir, file), 'utf8');
35
+ messages.push(JSON.parse(data));
36
+ }
37
+ catch {
38
+ // Skip files that cannot be read or parsed
39
+ }
40
+ }
41
+ return messages;
42
+ }
43
+ clear(recipientKey) {
44
+ const dir = this.recipientDir(recipientKey);
45
+ if (!fs.existsSync(dir))
46
+ return;
47
+ const files = fs.readdirSync(dir);
48
+ for (const file of files) {
49
+ if (file.endsWith('.json')) {
50
+ fs.unlinkSync(path.join(dir, file));
51
+ }
52
+ }
53
+ }
54
+ }
55
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/relay/store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAQlC,MAAM,OAAO,YAAY;IACf,UAAU,CAAS;IAE3B,YAAY,UAAkB;QAC5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAEO,YAAY,CAAC,SAAiB;QACpC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC,YAAoB,EAAE,OAAsB;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC5C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC;QAC7D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,CAAC,YAAoB;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAoB,EAAE,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;gBAC3D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAkB,CAAC,CAAC;YACnD,CAAC;YAAC,MAAM,CAAC;gBACP,2CAA2C;YAC7C,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,YAAoB;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO;QAChC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rookdaemon/agora",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "A coordination network for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,15 +29,22 @@
29
29
  "author": "",
30
30
  "license": "MIT",
31
31
  "devDependencies": {
32
+ "@types/express": "^5.0.0",
33
+ "@types/jsonwebtoken": "^9.0.9",
32
34
  "@types/node": "^25.1.0",
35
+ "@types/supertest": "^6.0.2",
33
36
  "@types/ws": "^8.18.1",
34
37
  "@typescript-eslint/eslint-plugin": "^8.54.0",
35
38
  "@typescript-eslint/parser": "^8.54.0",
36
39
  "eslint": "^9.39.2",
40
+ "supertest": "^7.1.0",
37
41
  "tsx": "^4.21.0",
38
42
  "typescript": "^5.9.3"
39
43
  },
40
44
  "dependencies": {
45
+ "express": "^5.2.1",
46
+ "express-rate-limit": "^8.2.1",
47
+ "jsonwebtoken": "^9.0.3",
41
48
  "ws": "^8.19.0"
42
49
  }
43
50
  }