@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.
- package/index.ts +100 -21
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -141,26 +141,116 @@ function stopAutoImport() {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
//
|
|
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
|
|
148
|
-
const
|
|
149
|
-
|
|
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
|
-
|
|
152
|
-
id:
|
|
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
|
-
|
|
583
|
-
|
|
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
|
}
|