@johngalt5/bsv-overlay 0.2.14 → 0.2.16

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 (2) hide show
  1. package/index.ts +100 -21
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -141,26 +141,116 @@ function stopAutoImport() {
141
141
  }
142
142
  }
143
143
 
144
- // Wake the agent via gateway WebSocket JSON-RPC (event-driven, zero polling)
144
+ // Discover the gateway WebSocket port from environment
145
+ function getGatewayWsUrl(): string {
146
+ const port = process.env.CLAWDBOT_GATEWAY_PORT || process.env.OPENCLAW_GATEWAY_PORT || '18789';
147
+ return `ws://127.0.0.1:${port}`;
148
+ }
149
+
150
+ // Read the gateway auth token from env vars or config files
151
+ function getGatewayToken(): string | null {
152
+ const envToken = process.env.CLAWDBOT_GATEWAY_TOKEN || process.env.OPENCLAW_GATEWAY_TOKEN;
153
+ if (envToken) return envToken;
154
+
155
+ try {
156
+ const configPaths = [
157
+ path.join(process.env.HOME || '', '.openclaw', 'openclaw.json'),
158
+ path.join(process.env.HOME || '', '.clawdbot', 'clawdbot.json'),
159
+ ];
160
+ for (const p of configPaths) {
161
+ if (fs.existsSync(p)) {
162
+ const config = JSON.parse(fs.readFileSync(p, 'utf-8'));
163
+ const token = config?.gateway?.auth?.token;
164
+ if (token) return token;
165
+ }
166
+ }
167
+ } catch {}
168
+ return null;
169
+ }
170
+
171
+ // Wake the agent via gateway WebSocket with proper frame format
172
+ // Gateway uses { type: "req", id, method, params }, NOT JSON-RPC 2.0
145
173
  function wakeAgent(text: string, logger?: any) {
146
174
  try {
147
- const ws = new WebSocket('ws://127.0.0.1:18789');
148
- const timeout = setTimeout(() => { try { ws.close(); } catch {} }, 5000);
149
- ws.on('open', () => {
175
+ const token = getGatewayToken();
176
+ const ws = new WebSocket(getGatewayWsUrl());
177
+ const timeout = setTimeout(() => { try { ws.close(); } catch {} }, 8000);
178
+ let authenticated = false;
179
+ let reqId = 1;
180
+
181
+ function nextId() { return `overlay-${reqId++}`; }
182
+
183
+ function sendWake() {
150
184
  ws.send(JSON.stringify({
151
- jsonrpc: '2.0',
152
- id: `overlay-wake-${Date.now()}`,
185
+ type: 'req',
186
+ id: nextId(),
153
187
  method: 'cron.wake',
154
188
  params: { mode: 'now', text },
155
189
  }));
156
- clearTimeout(timeout);
157
- setTimeout(() => { try { ws.close(); } catch {} }, 500);
158
190
  logger?.info?.('[bsv-overlay] Agent woken via WebSocket');
191
+ clearTimeout(timeout);
192
+ setTimeout(() => { try { ws.close(); } catch {} }, 1000);
193
+ }
194
+
195
+ ws.on('message', (data) => {
196
+ try {
197
+ const msg = JSON.parse(data.toString());
198
+
199
+ // Handle auth challenge
200
+ if (msg.type === 'event' && msg.event === 'connect.challenge') {
201
+ const nonce = msg.payload?.nonce;
202
+ if (!token) {
203
+ logger?.warn?.('[bsv-overlay] No gateway token for auth challenge');
204
+ ws.close();
205
+ return;
206
+ }
207
+ ws.send(JSON.stringify({
208
+ type: 'req',
209
+ id: nextId(),
210
+ method: 'connect',
211
+ params: {
212
+ minProtocol: 3,
213
+ maxProtocol: 3,
214
+ client: {
215
+ id: 'cli',
216
+ displayName: 'BSV Overlay Plugin',
217
+ version: '0.2.16',
218
+ platform: process.platform,
219
+ mode: 'cli',
220
+ },
221
+ caps: [],
222
+ auth: { token },
223
+ role: 'operator',
224
+ },
225
+ }));
226
+ return;
227
+ }
228
+
229
+ // connect.ready event OR successful res to connect — both mean authenticated
230
+ if ((msg.type === 'event' && msg.event === 'connect.ready') ||
231
+ (msg.type === 'res' && msg.ok === true && !authenticated)) {
232
+ authenticated = true;
233
+ sendWake();
234
+ return;
235
+ }
236
+
237
+ // Failed connect response
238
+ if (msg.type === 'res' && msg.ok === false && !authenticated) {
239
+ logger?.warn?.('[bsv-overlay] Gateway auth failed:', msg.error?.message || 'unknown');
240
+ ws.close();
241
+ return;
242
+ }
243
+ } catch {}
159
244
  });
245
+
160
246
  ws.on('error', (err) => {
161
247
  clearTimeout(timeout);
162
248
  logger?.warn?.('[bsv-overlay] WebSocket wake failed:', err.message);
163
249
  });
250
+
251
+ ws.on('close', () => {
252
+ clearTimeout(timeout);
253
+ });
164
254
  } catch (err: any) {
165
255
  logger?.warn?.('[bsv-overlay] Wake failed:', err.message);
166
256
  }
@@ -579,19 +669,8 @@ export default function register(api) {
579
669
  if (regOutput.success) {
580
670
  api.log?.info?.('[bsv-overlay] Auto-registered on overlay network! Waking agent for service selection...');
581
671
  // Wake the agent to present service selection to the user
582
- try {
583
- const wakeText = `🎉 BSV Overlay: Auto-registered on the network! Two things to set up:\n\n1. **Agent name**: Ask the user what name they want for their agent on the network. The current default is "${env.AGENT_NAME}". If they want a different name, they need to set it in the plugin config (agentName) and re-register.\n\n2. **Services**: Ask the user which services they want to advertise. Call overlay({ action: "register" }) to get the full list of available services with descriptions and suggested prices, then present them to the user. Let them choose which ones to enable. For each selected service, call overlay({ action: "advertise", serviceId: "...", name: "...", description: "...", priceSats: N }).`;
584
- await fetch('http://127.0.0.1:18789', {
585
- method: 'POST',
586
- headers: { 'Content-Type': 'application/json' },
587
- body: JSON.stringify({
588
- jsonrpc: '2.0',
589
- id: `overlay-service-select-${Date.now()}`,
590
- method: 'cron.wake',
591
- params: { mode: 'now', text: wakeText },
592
- }),
593
- });
594
- } catch {}
672
+ const wakeText = `🎉 BSV Overlay: Auto-registered on the network! Two things to set up:\n\n1. **Agent name**: Ask the user what name they want for their agent on the network. The current default is "${env.AGENT_NAME}". If they want a different name, they need to set it in the plugin config (agentName) and re-register.\n\n2. **Services**: Ask the user which services they want to advertise. Call overlay({ action: "register" }) to get the full list of available services with descriptions and suggested prices, then present them to the user. Let them choose which ones to enable. For each selected service, call overlay({ action: "advertise", serviceId: "...", name: "...", description: "...", priceSats: N }).`;
673
+ wakeAgent(wakeText, api.log);
595
674
  }
596
675
  }
597
676
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johngalt5/bsv-overlay",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "Clawdbot BSV Overlay — agent discovery, service marketplace, and micropayments on the BSV blockchain",
5
5
  "type": "module",
6
6
  "files": [