@yefengr/remote-pi 0.7.4 → 0.7.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/README.md +81 -586
  2. package/dist/bin/supervisord.js +4 -5
  3. package/dist/bin/supervisord.js.map +1 -1
  4. package/dist/config.d.ts +1 -1
  5. package/dist/config.js +2 -2
  6. package/dist/daemon/cli-links.d.ts +30 -0
  7. package/dist/daemon/cli-links.js +134 -0
  8. package/dist/daemon/cli-links.js.map +1 -0
  9. package/dist/daemon/commands.d.ts +27 -0
  10. package/dist/daemon/commands.js +295 -0
  11. package/dist/daemon/commands.js.map +1 -0
  12. package/dist/daemon/control_protocol.d.ts +53 -31
  13. package/dist/daemon/control_protocol.js +8 -31
  14. package/dist/daemon/control_protocol.js.map +1 -1
  15. package/dist/daemon/cron_log.d.ts +2 -23
  16. package/dist/daemon/cron_log.js +10 -25
  17. package/dist/daemon/cron_log.js.map +1 -1
  18. package/dist/daemon/cron_registry.d.ts +3 -40
  19. package/dist/daemon/cron_registry.js +58 -103
  20. package/dist/daemon/cron_registry.js.map +1 -1
  21. package/dist/daemon/install-runtime.d.ts +10 -0
  22. package/dist/daemon/install-runtime.js +81 -0
  23. package/dist/daemon/install-runtime.js.map +1 -0
  24. package/dist/daemon/install.d.ts +3 -63
  25. package/dist/daemon/install.js +5 -289
  26. package/dist/daemon/install.js.map +1 -1
  27. package/dist/daemon/preflight.d.ts +51 -0
  28. package/dist/daemon/preflight.js +136 -0
  29. package/dist/daemon/preflight.js.map +1 -0
  30. package/dist/daemon/registry.d.ts +33 -45
  31. package/dist/daemon/registry.js +171 -117
  32. package/dist/daemon/registry.js.map +1 -1
  33. package/dist/daemon/rpc_child.d.ts +92 -146
  34. package/dist/daemon/rpc_child.js +336 -263
  35. package/dist/daemon/rpc_child.js.map +1 -1
  36. package/dist/daemon/status.d.ts +45 -0
  37. package/dist/daemon/status.js +87 -0
  38. package/dist/daemon/status.js.map +1 -0
  39. package/dist/daemon/supervisor-ipc.d.ts +2 -0
  40. package/dist/daemon/supervisor-ipc.js +20 -0
  41. package/dist/daemon/supervisor-ipc.js.map +1 -0
  42. package/dist/daemon/supervisor.d.ts +48 -71
  43. package/dist/daemon/supervisor.js +430 -420
  44. package/dist/daemon/supervisor.js.map +1 -1
  45. package/dist/extension_ui_bridge.d.ts +4 -3
  46. package/dist/extension_ui_bridge.js +10 -0
  47. package/dist/extension_ui_bridge.js.map +1 -1
  48. package/dist/index.d.ts +25 -230
  49. package/dist/index.js +515 -5553
  50. package/dist/index.js.map +1 -1
  51. package/dist/pairing/crypto.d.ts +8 -1
  52. package/dist/pairing/crypto.js +56 -6
  53. package/dist/pairing/crypto.js.map +1 -1
  54. package/dist/pairing/owner_storage.d.ts +42 -0
  55. package/dist/pairing/owner_storage.js +207 -0
  56. package/dist/pairing/owner_storage.js.map +1 -0
  57. package/dist/pairing/qr.d.ts +3 -42
  58. package/dist/pairing/qr.js +9 -59
  59. package/dist/pairing/qr.js.map +1 -1
  60. package/dist/pairing/storage.d.ts +3 -45
  61. package/dist/pairing/storage.js +10 -223
  62. package/dist/pairing/storage.js.map +1 -1
  63. package/dist/protocol/types.d.ts +1 -1
  64. package/dist/protocol/v2/schemas.d.ts +1 -1
  65. package/dist/protocol/v2/schemas.js +1 -1
  66. package/dist/protocol/v2/schemas.js.map +1 -1
  67. package/dist/runtime/owner_router.d.ts +16 -0
  68. package/dist/runtime/owner_router.js +37 -0
  69. package/dist/runtime/owner_router.js.map +1 -0
  70. package/dist/session/ipc.d.ts +1 -22
  71. package/dist/session/ipc.js +4 -11
  72. package/dist/session/ipc.js.map +1 -1
  73. package/dist/session/local_config.d.ts +4 -47
  74. package/dist/session/local_config.js +19 -101
  75. package/dist/session/local_config.js.map +1 -1
  76. package/dist/transport/peer_channel.d.ts +25 -39
  77. package/dist/transport/peer_channel.js +74 -131
  78. package/dist/transport/peer_channel.js.map +1 -1
  79. package/dist/transport/relay_client.d.ts +26 -70
  80. package/dist/transport/relay_client.js +37 -106
  81. package/dist/transport/relay_client.js.map +1 -1
  82. package/docs/daemon.md +91 -207
  83. package/package.json +21 -17
  84. package/dist/daemon/id.d.ts +0 -24
  85. package/dist/daemon/id.js +0 -36
  86. package/dist/daemon/id.js.map +0 -1
  87. package/dist/mcp/mesh_result.d.ts +0 -10
  88. package/dist/mcp/mesh_result.js +0 -42
  89. package/dist/mcp/mesh_result.js.map +0 -1
  90. package/dist/mcp/mesh_server.d.ts +0 -16
  91. package/dist/mcp/mesh_server.js +0 -327
  92. package/dist/mcp/mesh_server.js.map +0 -1
  93. package/dist/mesh/canonical.d.ts +0 -30
  94. package/dist/mesh/canonical.js +0 -61
  95. package/dist/mesh/canonical.js.map +0 -1
  96. package/dist/mesh/client.d.ts +0 -18
  97. package/dist/mesh/client.js +0 -125
  98. package/dist/mesh/client.js.map +0 -1
  99. package/dist/mesh/encoding.d.ts +0 -38
  100. package/dist/mesh/encoding.js +0 -216
  101. package/dist/mesh/encoding.js.map +0 -1
  102. package/dist/mesh/self_revoke.d.ts +0 -73
  103. package/dist/mesh/self_revoke.js +0 -401
  104. package/dist/mesh/self_revoke.js.map +0 -1
  105. package/dist/mesh/siblings.d.ts +0 -49
  106. package/dist/mesh/siblings.js +0 -159
  107. package/dist/mesh/siblings.js.map +0 -1
  108. package/dist/mesh/types.d.ts +0 -34
  109. package/dist/mesh/types.js +0 -11
  110. package/dist/mesh/types.js.map +0 -1
  111. package/dist/mesh/verify.d.ts +0 -17
  112. package/dist/mesh/verify.js +0 -86
  113. package/dist/mesh/verify.js.map +0 -1
  114. package/dist/rooms.d.ts +0 -29
  115. package/dist/rooms.js +0 -57
  116. package/dist/rooms.js.map +0 -1
  117. package/dist/session/bridge.d.ts +0 -37
  118. package/dist/session/bridge.js +0 -130
  119. package/dist/session/bridge.js.map +0 -1
  120. package/dist/session/broker.d.ts +0 -189
  121. package/dist/session/broker.js +0 -507
  122. package/dist/session/broker.js.map +0 -1
  123. package/dist/session/broker_remote.d.ts +0 -74
  124. package/dist/session/broker_remote.js +0 -583
  125. package/dist/session/broker_remote.js.map +0 -1
  126. package/dist/session/cwd_lock.d.ts +0 -33
  127. package/dist/session/cwd_lock.js +0 -126
  128. package/dist/session/cwd_lock.js.map +0 -1
  129. package/dist/session/envelope.d.ts +0 -33
  130. package/dist/session/envelope.js +0 -117
  131. package/dist/session/envelope.js.map +0 -1
  132. package/dist/session/global_config.d.ts +0 -33
  133. package/dist/session/global_config.js +0 -73
  134. package/dist/session/global_config.js.map +0 -1
  135. package/dist/session/leader_election.d.ts +0 -32
  136. package/dist/session/leader_election.js +0 -106
  137. package/dist/session/leader_election.js.map +0 -1
  138. package/dist/session/mesh_node.d.ts +0 -116
  139. package/dist/session/mesh_node.js +0 -573
  140. package/dist/session/mesh_node.js.map +0 -1
  141. package/dist/session/peer.d.ts +0 -139
  142. package/dist/session/peer.js +0 -451
  143. package/dist/session/peer.js.map +0 -1
  144. package/dist/session/peer_inventory.d.ts +0 -13
  145. package/dist/session/peer_inventory.js +0 -48
  146. package/dist/session/peer_inventory.js.map +0 -1
  147. package/dist/session/peer_limits.d.ts +0 -9
  148. package/dist/session/peer_limits.js +0 -21
  149. package/dist/session/peer_limits.js.map +0 -1
  150. package/dist/session/setup_wizard.d.ts +0 -39
  151. package/dist/session/setup_wizard.js +0 -63
  152. package/dist/session/setup_wizard.js.map +0 -1
  153. package/dist/session/tools.d.ts +0 -24
  154. package/dist/session/tools.js +0 -252
  155. package/dist/session/tools.js.map +0 -1
  156. package/dist/session/wizard.d.ts +0 -13
  157. package/dist/session/wizard.js +0 -20
  158. package/dist/session/wizard.js.map +0 -1
  159. package/dist/transport/pi_forward_client.d.ts +0 -29
  160. package/dist/transport/pi_forward_client.js +0 -62
  161. package/dist/transport/pi_forward_client.js.map +0 -1
  162. package/dist/ui/footer.d.ts +0 -32
  163. package/dist/ui/footer.js +0 -34
  164. package/dist/ui/footer.js.map +0 -1
  165. package/skills/agent-network/SKILL.md +0 -310
@@ -1,91 +1,47 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import type { Ed25519Keypair } from "../pairing/crypto.js";
3
- export interface RoomMeta {
4
- name: string;
5
- cwd: string;
6
- /** Friendly model name (e.g. "claude-sonnet-4.5"). Optional — pi-ext sends
7
- * when `ExtensionContext.model` is available; relay/app tolerate absence. */
3
+ export type EndpointMetadata = {
4
+ kind: "daemon" | "interactive";
5
+ name?: string;
6
+ cwd?: string;
7
+ pid?: number;
8
+ started_at?: number;
8
9
  model?: string;
9
- }
10
- /** Control frame sent to relay (not routed to app peer). */
11
- export interface RoomMetaUpdateFrame {
12
- type: "room_meta_update";
13
- room_id: string;
14
- meta: {
15
- model?: string;
16
- };
17
- }
18
- export interface ConnectOptions {
19
- roomId?: string;
20
- roomMeta?: RoomMeta;
21
- }
22
- /** Relay rejected hello because another peer already holds (pubkey, room_id). */
23
- export declare class RoomAlreadyOpenError extends Error {
24
- readonly roomId: string | undefined;
25
- constructor(roomId: string | undefined);
26
- }
10
+ thinking?: string;
11
+ working?: boolean;
12
+ };
13
+ export type HostConnectOptions = {
14
+ role: "host";
15
+ endpointId: string;
16
+ runtimeInstanceId: string;
17
+ metadata: EndpointMetadata;
18
+ authorizedOwnerIds: readonly string[];
19
+ };
20
+ export type OwnerConnectOptions = {
21
+ role: "owner";
22
+ };
23
+ export type ConnectOptions = HostConnectOptions | OwnerConnectOptions;
27
24
  export interface RelayClientEvents {
28
- /** A single JSONL line delivered by the relay (outer envelope). */
29
25
  message: [line: string];
30
26
  close: [];
31
27
  error: [err: Error];
32
28
  }
33
- /**
34
- * Thin WebSocket client for the Remote Pi relay.
35
- *
36
- * Lifecycle:
37
- * const relay = new RelayClient(url, ed25519Keypair)
38
- * await relay.connect() // opens WS + runs Ed25519 challenge-response
39
- * relay.on("message", line => …) // outer envelopes: { peer, ct }
40
- * relay.send(jsonLine) // write to relay
41
- * relay.close()
42
- *
43
- * Auth sequence (pairing.md §Challenge-response):
44
- * → { type:"hello", pubkey: "<Ed25519 pubkey base64>" }
45
- * ← { type:"challenge", nonce: "<32 bytes base64>" }
46
- * → { type:"auth", sig: "<Ed25519 sig base64>" }
47
- */
29
+ /** Authenticated WebSocket client for the endpoint relay. */
48
30
  export declare class RelayClient extends EventEmitter {
49
31
  private readonly url;
50
32
  private readonly keypair;
51
33
  private ws;
52
- /** Epoch ms of the last inbound frame (message / relay ping / pong). */
53
34
  private lastActivityAt;
54
35
  private livenessTimer;
55
36
  constructor(url: string, keypair: Ed25519Keypair);
56
- /**
57
- * Connects and completes Ed25519 auth. Resolves when relay is ready.
58
- *
59
- * `options.roomId` (12-char id derived from cwd, see `src/rooms.ts`) is
60
- * included in the hello so the relay can multiplex N concurrent peers
61
- * with the same Ed25519 pubkey but different rooms (one pi-ext per cwd).
62
- * Omitting `roomId` is backward-compat with old relays (treated as the
63
- * default "main" room server-side).
64
- *
65
- * Throws `RoomAlreadyOpenError` if the relay rejects the hello because
66
- * another peer already holds the (pubkey, room_id) tuple. Caller (e.g.
67
- * `_cmdStart`) maps that to a clearer UI message.
68
- */
69
37
  connect(options?: ConnectOptions): Promise<void>;
70
- /** True only while the authenticated Relay WebSocket is currently open. */
71
38
  isOpen(): boolean;
72
- /** Sends a raw line to the relay (caller is responsible for framing). */
73
39
  send(line: string): void;
74
- /**
75
- * Sends a control frame to the relay (not routed to app peer). Used for
76
- * out-of-band metadata updates like `room_meta_update`. Silently no-ops if
77
- * the WS isn't open (best-effort: control frames are observational; we
78
- * don't want them throwing inside SDK event callbacks).
79
- */
80
40
  sendControl(frame: object): void;
81
41
  close(): void;
82
- /** Force-close the WS when no inbound frame has arrived for
83
- * `LIVENESS_TIMEOUT_MS` — see the constant's doc for why. `terminate()`
84
- * fires `close`, which the owner turns into a reconnect. */
85
- private _startLiveness;
86
- private _stopLiveness;
87
- private _authenticate;
88
- /** Waits for the next single WS message with a timeout. */
89
- private _nextMsg;
90
- private _rawSend;
42
+ private startLiveness;
43
+ private stopLiveness;
44
+ private authenticate;
45
+ private nextMessage;
46
+ private rawSend;
91
47
  }
@@ -2,48 +2,13 @@ import { EventEmitter } from "node:events";
2
2
  import WebSocket from "ws";
3
3
  import { ed25519Sign } from "../pairing/crypto.js";
4
4
  const AUTH_TIMEOUT_MS = 5_000;
5
- /**
6
- * Liveness watchdog. The relay sends a WS Ping every ~25s (relay `peer.rs`),
7
- * so a healthy connection sees inbound frames at least that often. If NOTHING
8
- * arrives for this long the socket is silently dead — NAT/router idle drop,
9
- * laptop sleep, or the relay/Cloudflare reaping the connection WITHOUT a clean
10
- * close frame. That half-open case never fires `close`, so reconnect never
11
- * triggers and a background daemon sits "online" but dead after a few idle
12
- * hours. We force-close on timeout so `close` drives the caller's reconnect.
13
- */
14
- const LIVENESS_TIMEOUT_MS = 70_000; // ~2.8 missed relay pings → confidently dead
5
+ const LIVENESS_TIMEOUT_MS = 70_000;
15
6
  const LIVENESS_CHECK_MS = 20_000;
16
- /** Relay rejected hello because another peer already holds (pubkey, room_id). */
17
- export class RoomAlreadyOpenError extends Error {
18
- roomId;
19
- constructor(roomId) {
20
- super(roomId
21
- ? `relay rejected hello: room ${roomId} already open for this peer`
22
- : "relay rejected hello: peer already connected");
23
- this.roomId = roomId;
24
- this.name = "RoomAlreadyOpenError";
25
- }
26
- }
27
- /**
28
- * Thin WebSocket client for the Remote Pi relay.
29
- *
30
- * Lifecycle:
31
- * const relay = new RelayClient(url, ed25519Keypair)
32
- * await relay.connect() // opens WS + runs Ed25519 challenge-response
33
- * relay.on("message", line => …) // outer envelopes: { peer, ct }
34
- * relay.send(jsonLine) // write to relay
35
- * relay.close()
36
- *
37
- * Auth sequence (pairing.md §Challenge-response):
38
- * → { type:"hello", pubkey: "<Ed25519 pubkey base64>" }
39
- * ← { type:"challenge", nonce: "<32 bytes base64>" }
40
- * → { type:"auth", sig: "<Ed25519 sig base64>" }
41
- */
7
+ /** Authenticated WebSocket client for the endpoint relay. */
42
8
  export class RelayClient extends EventEmitter {
43
9
  url;
44
10
  keypair;
45
11
  ws = null;
46
- /** Epoch ms of the last inbound frame (message / relay ping / pong). */
47
12
  lastActivityAt = 0;
48
13
  livenessTimer = null;
49
14
  constructor(url, keypair) {
@@ -51,31 +16,14 @@ export class RelayClient extends EventEmitter {
51
16
  this.url = url;
52
17
  this.keypair = keypair;
53
18
  }
54
- // ── Public API ──────────────────────────────────────────────────────────────
55
- /**
56
- * Connects and completes Ed25519 auth. Resolves when relay is ready.
57
- *
58
- * `options.roomId` (12-char id derived from cwd, see `src/rooms.ts`) is
59
- * included in the hello so the relay can multiplex N concurrent peers
60
- * with the same Ed25519 pubkey but different rooms (one pi-ext per cwd).
61
- * Omitting `roomId` is backward-compat with old relays (treated as the
62
- * default "main" room server-side).
63
- *
64
- * Throws `RoomAlreadyOpenError` if the relay rejects the hello because
65
- * another peer already holds the (pubkey, room_id) tuple. Caller (e.g.
66
- * `_cmdStart`) maps that to a clearer UI message.
67
- */
68
- async connect(options = {}) {
19
+ async connect(options = { role: "owner" }) {
69
20
  return new Promise((resolve, reject) => {
70
21
  const ws = new WebSocket(this.url);
71
22
  this.ws = ws;
72
23
  ws.on("error", (err) => reject(err));
73
24
  ws.on("open", async () => {
74
25
  try {
75
- await this._authenticate(ws, options);
76
- // Auth done — wire persistent message handler. Every inbound frame
77
- // (data, plus the relay's keepalive ping/pong below) refreshes the
78
- // liveness clock.
26
+ await this.authenticate(ws, options);
79
27
  this.lastActivityAt = Date.now();
80
28
  ws.on("message", (raw) => {
81
29
  this.lastActivityAt = Date.now();
@@ -86,17 +34,13 @@ export class RelayClient extends EventEmitter {
86
34
  this.emit("message", trimmed);
87
35
  }
88
36
  });
89
- // The relay pings every ~25s; `ws` auto-replies Pong (keeping the
90
- // relay's view of us alive). The relay ignores client pings rather
91
- // than ponging, so these inbound pings — not a ping/pong we initiate
92
- // — are our liveness signal.
93
37
  ws.on("ping", () => { this.lastActivityAt = Date.now(); });
94
38
  ws.on("pong", () => { this.lastActivityAt = Date.now(); });
95
39
  ws.on("close", () => {
96
- this._stopLiveness();
40
+ this.stopLiveness();
97
41
  this.emit("close");
98
42
  });
99
- this._startLiveness(ws);
43
+ this.startLiveness(ws);
100
44
  resolve();
101
45
  }
102
46
  catch (err) {
@@ -106,62 +50,56 @@ export class RelayClient extends EventEmitter {
106
50
  });
107
51
  });
108
52
  }
109
- /** True only while the authenticated Relay WebSocket is currently open. */
110
53
  isOpen() {
111
54
  return this.ws?.readyState === WebSocket.OPEN;
112
55
  }
113
- /** Sends a raw line to the relay (caller is responsible for framing). */
114
56
  send(line) {
115
57
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
116
58
  throw new Error("relay: not connected");
117
59
  }
118
60
  this.ws.send(line);
119
61
  }
120
- /**
121
- * Sends a control frame to the relay (not routed to app peer). Used for
122
- * out-of-band metadata updates like `room_meta_update`. Silently no-ops if
123
- * the WS isn't open (best-effort: control frames are observational; we
124
- * don't want them throwing inside SDK event callbacks).
125
- */
126
62
  sendControl(frame) {
127
63
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN)
128
64
  return;
129
65
  this.ws.send(JSON.stringify(frame));
130
66
  }
131
67
  close() {
132
- this._stopLiveness();
68
+ this.stopLiveness();
133
69
  this.ws?.close();
134
70
  this.ws = null;
135
71
  }
136
- // ── Liveness watchdog ─────────────────────────────────────────────────────
137
- /** Force-close the WS when no inbound frame has arrived for
138
- * `LIVENESS_TIMEOUT_MS` — see the constant's doc for why. `terminate()`
139
- * fires `close`, which the owner turns into a reconnect. */
140
- _startLiveness(ws) {
141
- this._stopLiveness();
72
+ startLiveness(ws) {
73
+ this.stopLiveness();
142
74
  this.livenessTimer = setInterval(() => {
143
75
  if (Date.now() - this.lastActivityAt > LIVENESS_TIMEOUT_MS) {
144
- this._stopLiveness();
76
+ this.stopLiveness();
145
77
  ws.terminate();
146
78
  }
147
79
  }, LIVENESS_CHECK_MS);
148
80
  }
149
- _stopLiveness() {
150
- if (this.livenessTimer) {
151
- clearInterval(this.livenessTimer);
152
- this.livenessTimer = null;
153
- }
81
+ stopLiveness() {
82
+ if (!this.livenessTimer)
83
+ return;
84
+ clearInterval(this.livenessTimer);
85
+ this.livenessTimer = null;
154
86
  }
155
- // ── Auth ────────────────────────────────────────────────────────────────────
156
- async _authenticate(ws, opts) {
157
- const pubkeyB64 = Buffer.from(this.keypair.publicKey).toString("base64");
158
- const hello = { type: "hello", pubkey: pubkeyB64 };
159
- if (opts.roomId)
160
- hello.room_id = opts.roomId;
161
- if (opts.roomMeta)
162
- hello.room_meta = opts.roomMeta;
163
- this._rawSend(ws, JSON.stringify(hello));
164
- const challengeRaw = await this._nextMsg(ws);
87
+ async authenticate(ws, options) {
88
+ const pubkey = Buffer.from(this.keypair.publicKey).toString("base64");
89
+ const hello = options.role === "host"
90
+ ? {
91
+ type: "hello",
92
+ protocol_version: 2,
93
+ role: "host",
94
+ pubkey,
95
+ endpoint_id: options.endpointId,
96
+ runtime_instance_id: options.runtimeInstanceId,
97
+ metadata: options.metadata,
98
+ authorized_owner_ids: options.authorizedOwnerIds,
99
+ }
100
+ : { type: "hello", protocol_version: 2, role: "owner", pubkey };
101
+ this.rawSend(ws, JSON.stringify(hello));
102
+ const challengeRaw = await this.nextMessage(ws);
165
103
  let challenge;
166
104
  try {
167
105
  challenge = JSON.parse(challengeRaw);
@@ -170,27 +108,20 @@ export class RelayClient extends EventEmitter {
170
108
  throw new Error(`relay auth_failed: not JSON: ${challengeRaw}`);
171
109
  }
172
110
  if (challenge.type === "error") {
173
- const code = challenge.code ?? "";
174
- if (code === "room_already_open") {
175
- throw new RoomAlreadyOpenError(opts.roomId);
176
- }
177
- throw new Error(`relay rejected hello: ${code || challenge.message || "unknown"}`);
111
+ const detail = challenge.code || challenge.message || "unknown";
112
+ throw new Error(`relay rejected hello: ${detail}`);
178
113
  }
179
114
  if (challenge.type !== "challenge" || !challenge.nonce) {
180
115
  throw new Error(`relay auth_failed: expected challenge, got ${challengeRaw}`);
181
116
  }
182
117
  const nonce = Buffer.from(challenge.nonce, "base64");
183
- const sig = ed25519Sign(this.keypair.secretKey, nonce);
184
118
  const auth = {
185
119
  type: "auth",
186
- sig: Buffer.from(sig).toString("base64"),
120
+ sig: Buffer.from(ed25519Sign(this.keypair.secretKey, nonce)).toString("base64"),
187
121
  };
188
- this._rawSend(ws, JSON.stringify(auth));
189
- // Relay does not send an explicit "ok" — it simply starts routing.
190
- // Proceed immediately after sending auth.
122
+ this.rawSend(ws, JSON.stringify(auth));
191
123
  }
192
- /** Waits for the next single WS message with a timeout. */
193
- _nextMsg(ws) {
124
+ nextMessage(ws) {
194
125
  return new Promise((resolve, reject) => {
195
126
  const timer = setTimeout(() => reject(new Error("relay auth timeout")), AUTH_TIMEOUT_MS);
196
127
  ws.once("message", (raw) => {
@@ -199,7 +130,7 @@ export class RelayClient extends EventEmitter {
199
130
  });
200
131
  });
201
132
  }
202
- _rawSend(ws, data) {
133
+ rawSend(ws, data) {
203
134
  ws.send(data);
204
135
  }
205
136
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relay_client.js","sourceRoot":"","sources":["../../src/transport/relay_client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relay_client.js","sourceRoot":"","sources":["../../src/transport/relay_client.ts"],"names":[],"mappings":"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"}