openclaw-overlay-plugin 0.7.33 → 0.7.35
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 +3 -1
- package/SKILL.md +14 -0
- package/dist/index.js +106 -61
- package/dist/src/core/wallet.js +4 -0
- package/dist/src/scripts/baemail/commands.js +17 -6
- package/dist/src/scripts/config.d.ts +1 -1
- package/dist/src/scripts/config.js +3 -3
- package/dist/src/scripts/overlay/discover.js +3 -1
- package/index.ts +103 -63
- package/openclaw.plugin.json +20 -0
- package/package.json +1 -1
- package/src/core/wallet.ts +6 -0
- package/src/scripts/baemail/commands.ts +17 -6
- package/src/scripts/config.ts +3 -3
- package/src/scripts/overlay/discover.ts +3 -1
- package/dist/cli-main.d.ts +0 -7
- package/dist/cli-main.js +0 -192
- package/dist/cli.d.ts +0 -8
- package/dist/cli.js +0 -14
- package/dist/core/config.d.ts +0 -11
- package/dist/core/config.js +0 -13
- package/dist/core/index.d.ts +0 -25
- package/dist/core/index.js +0 -26
- package/dist/core/payment.d.ts +0 -16
- package/dist/core/payment.js +0 -94
- package/dist/core/types.d.ts +0 -94
- package/dist/core/types.js +0 -4
- package/dist/core/verify.d.ts +0 -28
- package/dist/core/verify.js +0 -104
- package/dist/core/wallet.d.ts +0 -99
- package/dist/core/wallet.js +0 -219
- package/dist/scripts/baemail/commands.d.ts +0 -64
- package/dist/scripts/baemail/commands.js +0 -259
- package/dist/scripts/baemail/handler.d.ts +0 -36
- package/dist/scripts/baemail/handler.js +0 -284
- package/dist/scripts/baemail/index.d.ts +0 -5
- package/dist/scripts/baemail/index.js +0 -5
- package/dist/scripts/config.d.ts +0 -48
- package/dist/scripts/config.js +0 -68
- package/dist/scripts/index.d.ts +0 -7
- package/dist/scripts/index.js +0 -7
- package/dist/scripts/messaging/connect.d.ts +0 -8
- package/dist/scripts/messaging/connect.js +0 -114
- package/dist/scripts/messaging/handlers.d.ts +0 -21
- package/dist/scripts/messaging/handlers.js +0 -334
- package/dist/scripts/messaging/inbox.d.ts +0 -11
- package/dist/scripts/messaging/inbox.js +0 -51
- package/dist/scripts/messaging/index.d.ts +0 -8
- package/dist/scripts/messaging/index.js +0 -8
- package/dist/scripts/messaging/poll.d.ts +0 -7
- package/dist/scripts/messaging/poll.js +0 -52
- package/dist/scripts/messaging/send.d.ts +0 -7
- package/dist/scripts/messaging/send.js +0 -43
- package/dist/scripts/output.d.ts +0 -12
- package/dist/scripts/output.js +0 -19
- package/dist/scripts/overlay/discover.d.ts +0 -7
- package/dist/scripts/overlay/discover.js +0 -72
- package/dist/scripts/overlay/index.d.ts +0 -7
- package/dist/scripts/overlay/index.js +0 -7
- package/dist/scripts/overlay/registration.d.ts +0 -19
- package/dist/scripts/overlay/registration.js +0 -176
- package/dist/scripts/overlay/services.d.ts +0 -29
- package/dist/scripts/overlay/services.js +0 -167
- package/dist/scripts/overlay/transaction.d.ts +0 -42
- package/dist/scripts/overlay/transaction.js +0 -103
- package/dist/scripts/payment/build.d.ts +0 -24
- package/dist/scripts/payment/build.js +0 -54
- package/dist/scripts/payment/commands.d.ts +0 -15
- package/dist/scripts/payment/commands.js +0 -73
- package/dist/scripts/payment/index.d.ts +0 -6
- package/dist/scripts/payment/index.js +0 -6
- package/dist/scripts/payment/types.d.ts +0 -56
- package/dist/scripts/payment/types.js +0 -4
- package/dist/scripts/services/index.d.ts +0 -6
- package/dist/scripts/services/index.js +0 -6
- package/dist/scripts/services/queue.d.ts +0 -11
- package/dist/scripts/services/queue.js +0 -28
- package/dist/scripts/services/request.d.ts +0 -7
- package/dist/scripts/services/request.js +0 -82
- package/dist/scripts/services/respond.d.ts +0 -11
- package/dist/scripts/services/respond.js +0 -132
- package/dist/scripts/types.d.ts +0 -107
- package/dist/scripts/types.js +0 -4
- package/dist/scripts/utils/index.d.ts +0 -6
- package/dist/scripts/utils/index.js +0 -6
- package/dist/scripts/utils/merkle.d.ts +0 -12
- package/dist/scripts/utils/merkle.js +0 -47
- package/dist/scripts/utils/storage.d.ts +0 -66
- package/dist/scripts/utils/storage.js +0 -211
- package/dist/scripts/utils/woc.d.ts +0 -26
- package/dist/scripts/utils/woc.js +0 -91
- package/dist/scripts/wallet/balance.d.ts +0 -22
- package/dist/scripts/wallet/balance.js +0 -240
- package/dist/scripts/wallet/identity.d.ts +0 -70
- package/dist/scripts/wallet/identity.js +0 -151
- package/dist/scripts/wallet/index.d.ts +0 -6
- package/dist/scripts/wallet/index.js +0 -6
- package/dist/scripts/wallet/setup.d.ts +0 -15
- package/dist/scripts/wallet/setup.js +0 -105
- package/dist/scripts/x-verification/commands.d.ts +0 -27
- package/dist/scripts/x-verification/commands.js +0 -222
- package/dist/scripts/x-verification/index.d.ts +0 -4
- package/dist/scripts/x-verification/index.js +0 -4
- package/dist/services/built-in/api-proxy/index.d.ts +0 -6
- package/dist/services/built-in/api-proxy/index.js +0 -23
- package/dist/services/built-in/code-develop/index.d.ts +0 -6
- package/dist/services/built-in/code-develop/index.js +0 -23
- package/dist/services/built-in/code-review/index.d.ts +0 -10
- package/dist/services/built-in/code-review/index.js +0 -51
- package/dist/services/built-in/image-analysis/index.d.ts +0 -6
- package/dist/services/built-in/image-analysis/index.js +0 -33
- package/dist/services/built-in/memory-store/index.d.ts +0 -6
- package/dist/services/built-in/memory-store/index.js +0 -22
- package/dist/services/built-in/roulette/index.d.ts +0 -6
- package/dist/services/built-in/roulette/index.js +0 -27
- package/dist/services/built-in/summarize/index.d.ts +0 -6
- package/dist/services/built-in/summarize/index.js +0 -21
- package/dist/services/built-in/tell-joke/handler.d.ts +0 -7
- package/dist/services/built-in/tell-joke/handler.js +0 -122
- package/dist/services/built-in/tell-joke/index.d.ts +0 -9
- package/dist/services/built-in/tell-joke/index.js +0 -31
- package/dist/services/built-in/translate/index.d.ts +0 -6
- package/dist/services/built-in/translate/index.js +0 -21
- package/dist/services/built-in/web-research/index.d.ts +0 -9
- package/dist/services/built-in/web-research/index.js +0 -51
- package/dist/services/index.d.ts +0 -13
- package/dist/services/index.js +0 -14
- package/dist/services/loader.d.ts +0 -77
- package/dist/services/loader.js +0 -292
- package/dist/services/manager.d.ts +0 -86
- package/dist/services/manager.js +0 -255
- package/dist/services/registry.d.ts +0 -98
- package/dist/services/registry.js +0 -204
- package/dist/services/types.d.ts +0 -230
- package/dist/services/types.js +0 -30
- package/dist/test/cli.test.d.ts +0 -7
- package/dist/test/cli.test.js +0 -329
- package/dist/test/comprehensive-overlay.test.d.ts +0 -13
- package/dist/test/comprehensive-overlay.test.js +0 -593
- package/dist/test/key-derivation.test.d.ts +0 -12
- package/dist/test/key-derivation.test.js +0 -86
- package/dist/test/overlay-submit.test.d.ts +0 -10
- package/dist/test/overlay-submit.test.js +0 -460
- package/dist/test/request-response-flow.test.d.ts +0 -5
- package/dist/test/request-response-flow.test.js +0 -209
- package/dist/test/service-system.test.d.ts +0 -5
- package/dist/test/service-system.test.js +0 -190
- package/dist/test/utils/server-logic.d.ts +0 -98
- package/dist/test/utils/server-logic.js +0 -286
- package/dist/test/wallet.test.d.ts +0 -7
- package/dist/test/wallet.test.js +0 -146
package/README.md
CHANGED
|
@@ -33,7 +33,8 @@ After installing, you can configure the plugin in `~/.openclaw/openclaw.json` un
|
|
|
33
33
|
"agentDescription": "My agent on the overlay network",
|
|
34
34
|
"maxAutoPaySats": 200,
|
|
35
35
|
"dailyBudgetSats": 5000,
|
|
36
|
-
"chaintracksUrl": "https://chaintracks-us-1.bsvb.tech"
|
|
36
|
+
"chaintracksUrl": "https://chaintracks-us-1.bsvb.tech",
|
|
37
|
+
"arcUrl": "https://arc.gorillapool.io"
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
}
|
|
@@ -49,6 +50,7 @@ After installing, you can configure the plugin in `~/.openclaw/openclaw.json` un
|
|
|
49
50
|
| `walletDir` | `~/.openclaw/bsv-wallet` | Wallet storage directory |
|
|
50
51
|
| `overlayUrl` | `https://clawoverlay.com` | Overlay network server |
|
|
51
52
|
| `chaintracksUrl` | `https://chaintracks-us-1.bsvb.tech` | Custom SPV header server |
|
|
53
|
+
| `arcUrl` | (uses public ARC) | Custom ARC/Arcade server for broadcasting |
|
|
52
54
|
|
|
53
55
|
### Required: Enable Hooks
|
|
54
56
|
|
package/SKILL.md
CHANGED
|
@@ -45,6 +45,20 @@ On first run, the plugin auto-creates a wallet and wakes you. Guide the user thr
|
|
|
45
45
|
5. **Ask which services to offer**: Present the list from the onboard response, let user pick
|
|
46
46
|
6. **Advertise selected**: `overlay({ action: "advertise", ... })` for each
|
|
47
47
|
|
|
48
|
+
If you need to customize settings, tell the user to add them to their config under `plugins.entries["openclaw-overlay"]`:
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"plugins": {
|
|
52
|
+
"entries": {
|
|
53
|
+
"openclaw-overlay": {
|
|
54
|
+
"agentName": "...",
|
|
55
|
+
"overlayUrl": "..."
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
48
62
|
Do NOT use defaults without asking. Do NOT skip the name/description questions.
|
|
49
63
|
|
|
50
64
|
## Requesting Services
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,7 @@ function loadDailySpending(walletDir) {
|
|
|
38
38
|
return { date: today, totalSats: 0, transactions: [] };
|
|
39
39
|
}
|
|
40
40
|
function writeActivityEvent(event) {
|
|
41
|
-
const alertDir = path.join(process.env.HOME || '', '.openclaw', '
|
|
41
|
+
const alertDir = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay');
|
|
42
42
|
try {
|
|
43
43
|
fs.mkdirSync(alertDir, { recursive: true });
|
|
44
44
|
fs.appendFileSync(path.join(alertDir, 'activity-feed.jsonl'), JSON.stringify({ ...event, ts: Date.now() }) + '\n');
|
|
@@ -91,39 +91,39 @@ async function startAutoImport(env, cliPath, logger) {
|
|
|
91
91
|
continue;
|
|
92
92
|
if (utxo.value < 200)
|
|
93
93
|
continue; // skip dust
|
|
94
|
-
logger?.info?.(`[
|
|
94
|
+
logger?.info?.(`[openclaw-overlay] Auto-importing UTXO: ${utxo.tx_hash}:${utxo.tx_pos} (${utxo.value} sats)`);
|
|
95
95
|
try {
|
|
96
96
|
const importResult = await execFileAsync('node', [cliPath, 'import', utxo.tx_hash, String(utxo.tx_pos)], { env });
|
|
97
97
|
const importOutput = parseCliOutput(importResult.stdout);
|
|
98
98
|
if (importOutput.success) {
|
|
99
99
|
knownTxids.add(key);
|
|
100
|
-
logger?.info?.(`[
|
|
100
|
+
logger?.info?.(`[openclaw-overlay] Auto-imported ${utxo.value} sats from ${utxo.tx_hash}`);
|
|
101
101
|
// Clear onboarding flag since wallet is now funded
|
|
102
102
|
try {
|
|
103
|
-
const onboardingSentFile = path.join(process.env.HOME || '', '.openclaw', '
|
|
103
|
+
const onboardingSentFile = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'onboarding-sent.flag');
|
|
104
104
|
if (fs.existsSync(onboardingSentFile)) {
|
|
105
105
|
fs.unlinkSync(onboardingSentFile);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
catch { }
|
|
109
109
|
// Notify agent of successful import
|
|
110
|
-
wakeAgent(`💰 **Wallet Funded!**\n\nAuto-imported ${utxo.value} sats from transaction ${utxo.tx_hash.slice(0, 16)}...\n\nNotify the user their wallet has been funded.`, logger, { sessionKey: 'hook:
|
|
110
|
+
wakeAgent(`💰 **Wallet Funded!**\n\nAuto-imported ${utxo.value} sats from transaction ${utxo.tx_hash.slice(0, 16)}...\n\nNotify the user their wallet has been funded.`, logger, { sessionKey: 'hook:openclaw-overlay:import' });
|
|
111
111
|
// Check if registered, auto-register if not
|
|
112
112
|
try {
|
|
113
|
-
const regPath = path.join(process.env.HOME || '', '.openclaw', '
|
|
113
|
+
const regPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'registration.json');
|
|
114
114
|
if (!fs.existsSync(regPath)) {
|
|
115
|
-
logger?.info?.('[
|
|
115
|
+
logger?.info?.('[openclaw-overlay] Not yet registered — auto-registering...');
|
|
116
116
|
const regResult = await execFileAsync('node', [cliPath, 'register'], { env, timeout: 60000 });
|
|
117
117
|
const regOutput = parseCliOutput(regResult.stdout);
|
|
118
118
|
if (regOutput.success) {
|
|
119
|
-
logger?.info?.('[
|
|
119
|
+
logger?.info?.('[openclaw-overlay] Auto-registered on overlay network!');
|
|
120
120
|
// Auto-advertise services from config
|
|
121
121
|
await autoAdvertiseServices(env, cliPath, logger);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
catch (err) {
|
|
126
|
-
logger?.warn?.('[
|
|
126
|
+
logger?.warn?.('[openclaw-overlay] Auto-registration failed:', err.message);
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -139,7 +139,7 @@ async function startAutoImport(env, cliPath, logger) {
|
|
|
139
139
|
}, 30000); // Check every 30 seconds for faster onboarding
|
|
140
140
|
}
|
|
141
141
|
catch (err) {
|
|
142
|
-
logger?.warn?.('[
|
|
142
|
+
logger?.warn?.('[openclaw-overlay] Auto-import setup failed:', err.message);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
function stopAutoImport() {
|
|
@@ -162,7 +162,7 @@ async function autoAdvertiseServices(env, cliPath, logger) {
|
|
|
162
162
|
continue;
|
|
163
163
|
try {
|
|
164
164
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
165
|
-
const pluginConfig = config?.plugins?.entries?.['
|
|
165
|
+
const pluginConfig = config?.plugins?.entries?.['openclaw-overlay']?.config;
|
|
166
166
|
if (pluginConfig?.services && Array.isArray(pluginConfig.services)) {
|
|
167
167
|
servicesToAdvertise = pluginConfig.services;
|
|
168
168
|
break;
|
|
@@ -171,10 +171,10 @@ async function autoAdvertiseServices(env, cliPath, logger) {
|
|
|
171
171
|
catch { }
|
|
172
172
|
}
|
|
173
173
|
if (servicesToAdvertise.length === 0) {
|
|
174
|
-
logger?.info?.('[
|
|
174
|
+
logger?.info?.('[openclaw-overlay] No services configured for auto-advertising');
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
177
|
-
logger?.info?.(`[
|
|
177
|
+
logger?.info?.(`[openclaw-overlay] Auto-advertising ${servicesToAdvertise.length} services from config...`);
|
|
178
178
|
const advertised = [];
|
|
179
179
|
const failed = [];
|
|
180
180
|
for (const serviceId of servicesToAdvertise) {
|
|
@@ -194,12 +194,12 @@ async function autoAdvertiseServices(env, cliPath, logger) {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
if (advertised.length > 0)
|
|
197
|
-
logger?.info?.(`[
|
|
197
|
+
logger?.info?.(`[openclaw-overlay] Successfully advertised: ${advertised.join(', ')}`);
|
|
198
198
|
if (failed.length > 0)
|
|
199
|
-
logger?.warn?.(`[
|
|
199
|
+
logger?.warn?.(`[openclaw-overlay] Failed to advertise: ${failed.join(', ')}`);
|
|
200
200
|
}
|
|
201
201
|
catch (err) {
|
|
202
|
-
logger?.warn?.('[
|
|
202
|
+
logger?.warn?.('[openclaw-overlay] Auto-advertising failed:', err.message);
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
@@ -207,11 +207,11 @@ async function autoAdvertiseServices(env, cliPath, logger) {
|
|
|
207
207
|
* This is the standard way to invoke an agent with a specific context.
|
|
208
208
|
*/
|
|
209
209
|
function wakeAgent(text, logger, options = {}) {
|
|
210
|
-
const sessionKey = options.sessionKey || `hook:
|
|
210
|
+
const sessionKey = options.sessionKey || `hook:openclaw-overlay:${Date.now()}`;
|
|
211
211
|
const gatewayPort = getGatewayPort();
|
|
212
212
|
const httpToken = getHooksToken();
|
|
213
213
|
if (!httpToken) {
|
|
214
|
-
logger?.warn?.('[
|
|
214
|
+
logger?.warn?.('[openclaw-overlay] Skipped wakeAgent: OPENCLAW_HOOKS_TOKEN not set');
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
const url = `http://localhost:${gatewayPort}/hooks/agent`;
|
|
@@ -228,15 +228,15 @@ function wakeAgent(text, logger, options = {}) {
|
|
|
228
228
|
})
|
|
229
229
|
.then(async (res) => {
|
|
230
230
|
if (res.ok) {
|
|
231
|
-
logger?.info?.(`[
|
|
231
|
+
logger?.info?.(`[openclaw-overlay] Agent invoked via /hooks/agent (session: ${sessionKey})`);
|
|
232
232
|
}
|
|
233
233
|
else {
|
|
234
234
|
const body = await res.text().catch(() => '');
|
|
235
|
-
logger?.warn?.(`[
|
|
235
|
+
logger?.warn?.(`[openclaw-overlay] /hooks/agent failed: ${res.status} ${body}`);
|
|
236
236
|
}
|
|
237
237
|
})
|
|
238
238
|
.catch((err) => {
|
|
239
|
-
logger?.warn?.('[
|
|
239
|
+
logger?.warn?.('[openclaw-overlay] /hooks/agent error:', err.message);
|
|
240
240
|
});
|
|
241
241
|
}
|
|
242
242
|
function getGatewayPort() {
|
|
@@ -292,15 +292,15 @@ function startBackgroundService(env, cliPath, logger) {
|
|
|
292
292
|
requestCleanupInterval = setInterval(async () => {
|
|
293
293
|
if (serviceRunning) {
|
|
294
294
|
wokenRequests.clear();
|
|
295
|
-
logger?.debug?.('[
|
|
295
|
+
logger?.debug?.('[openclaw-overlay] Cleared stale request IDs');
|
|
296
296
|
// Also clean up old queue entries
|
|
297
297
|
try {
|
|
298
298
|
const { cleanupServiceQueue } = await import('./src/scripts/utils/storage.js');
|
|
299
299
|
cleanupServiceQueue();
|
|
300
|
-
logger?.debug?.('[
|
|
300
|
+
logger?.debug?.('[openclaw-overlay] Cleaned up old queue entries');
|
|
301
301
|
}
|
|
302
302
|
catch (err) {
|
|
303
|
-
logger?.warn?.('[
|
|
303
|
+
logger?.warn?.('[openclaw-overlay] Queue cleanup failed:', err.message);
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
}, 5 * 60 * 1000);
|
|
@@ -317,8 +317,8 @@ function startBackgroundService(env, cliPath, logger) {
|
|
|
317
317
|
for (const line of lines) {
|
|
318
318
|
try {
|
|
319
319
|
const event = JSON.parse(line);
|
|
320
|
-
logger?.debug?.(`[
|
|
321
|
-
const alertDir = path.join(process.env.HOME || '', '.openclaw', '
|
|
320
|
+
logger?.debug?.(`[openclaw-overlay] ${event.event || event.type || 'message'}:`, JSON.stringify(event).slice(0, 200));
|
|
321
|
+
const alertDir = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay');
|
|
322
322
|
fs.mkdirSync(alertDir, { recursive: true });
|
|
323
323
|
// Detect queued-for-agent events — invoke agent via /hooks/agent
|
|
324
324
|
// This is the PROVIDER side: someone requested our service
|
|
@@ -326,18 +326,18 @@ function startBackgroundService(env, cliPath, logger) {
|
|
|
326
326
|
const requestId = event.id || `${event.from}-${Date.now()}`;
|
|
327
327
|
// Check if already woken to prevent duplicate processing
|
|
328
328
|
if (wokenRequests.has(requestId)) {
|
|
329
|
-
logger?.debug?.(`[
|
|
329
|
+
logger?.debug?.(`[openclaw-overlay] Request ${requestId} already woken, skipping duplicate`);
|
|
330
330
|
return;
|
|
331
331
|
}
|
|
332
332
|
// Skip wake-up for already processed requests unless they're pending
|
|
333
333
|
if (event.action?.startsWith('already-') && !event.action.includes('pending')) {
|
|
334
|
-
logger?.debug?.(`[
|
|
334
|
+
logger?.debug?.(`[openclaw-overlay] Request ${requestId} already processed (${event.action}), skipping`);
|
|
335
335
|
return;
|
|
336
336
|
}
|
|
337
337
|
wokenRequests.add(requestId);
|
|
338
|
-
logger?.info?.(`[
|
|
338
|
+
logger?.info?.(`[openclaw-overlay] ⚡ Incoming ${event.serviceId} request from ${event.from?.slice(0, 12)}...`);
|
|
339
339
|
const wakeText = `⚡ Incoming overlay service request!\n\nService: ${event.serviceId}\nFrom: ${event.from}\nPaid: ${event.satoshisReceived || '?'} sats\n\nFulfill it now:\n1. overlay({ action: "pending-requests" })\n2. Process the ${event.serviceId} request using your capabilities\n3. overlay({ action: "fulfill", requestId: "${event.id}", recipientKey: "${event.from}", serviceId: "${event.serviceId}", result: { ... } })`;
|
|
340
|
-
wakeAgent(wakeText, logger, { sessionKey: `hook:
|
|
340
|
+
wakeAgent(wakeText, logger, { sessionKey: `hook:openclaw-overlay:${event.id || Date.now()}` });
|
|
341
341
|
}
|
|
342
342
|
// Detect service-response events — invoke agent to notify user
|
|
343
343
|
// This is the REQUESTER side: we requested a service, response came back
|
|
@@ -347,9 +347,9 @@ function startBackgroundService(env, cliPath, logger) {
|
|
|
347
347
|
const from = event.from || 'unknown';
|
|
348
348
|
const formatted = event.formatted || '';
|
|
349
349
|
const resultJson = event.result ? JSON.stringify(event.result, null, 2) : '(no result data)';
|
|
350
|
-
logger?.info?.(`[
|
|
350
|
+
logger?.info?.(`[openclaw-overlay] 📬 Response received for ${svcId} from ${from?.slice(0, 12)}... — status: ${status}`);
|
|
351
351
|
const wakeText = `📬 Overlay service response received!\n\nService: ${svcId}\nFrom: ${from}\nStatus: ${status}\n${formatted ? `\nSummary: ${formatted}` : ''}\n\nFull result:\n${resultJson}\n\nNotify the user of this response in a clear, human-readable format.`;
|
|
352
|
-
wakeAgent(wakeText, logger, { sessionKey: `hook:
|
|
352
|
+
wakeAgent(wakeText, logger, { sessionKey: `hook:openclaw-overlay:resp-${event.requestId || Date.now()}` });
|
|
353
353
|
}
|
|
354
354
|
// Write payment/activity notifications for ALL significant events
|
|
355
355
|
const notifEvent = categorizeEvent(event);
|
|
@@ -369,21 +369,21 @@ function startBackgroundService(env, cliPath, logger) {
|
|
|
369
369
|
try {
|
|
370
370
|
const event = JSON.parse(line);
|
|
371
371
|
if (event.event === 'connected') {
|
|
372
|
-
logger?.info?.('[
|
|
372
|
+
logger?.info?.('[openclaw-overlay] WebSocket relay connected');
|
|
373
373
|
}
|
|
374
374
|
else if (event.event === 'disconnected') {
|
|
375
|
-
logger?.warn?.('[
|
|
375
|
+
logger?.warn?.('[openclaw-overlay] WebSocket disconnected, reconnecting...');
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
378
|
catch {
|
|
379
|
-
logger?.debug?.(`[
|
|
379
|
+
logger?.debug?.(`[openclaw-overlay] ${line}`);
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
});
|
|
383
383
|
proc.on('exit', (code) => {
|
|
384
384
|
backgroundProcess = null;
|
|
385
385
|
if (serviceRunning) {
|
|
386
|
-
logger?.warn?.(`[
|
|
386
|
+
logger?.warn?.(`[openclaw-overlay] Background service exited (code ${code}), restarting in 5s...`);
|
|
387
387
|
setTimeout(spawnConnect, 5000);
|
|
388
388
|
}
|
|
389
389
|
});
|
|
@@ -405,8 +405,14 @@ function stopBackgroundService() {
|
|
|
405
405
|
stopAutoImport();
|
|
406
406
|
}
|
|
407
407
|
export default function register(api) {
|
|
408
|
-
// Capture config at registration time
|
|
409
|
-
|
|
408
|
+
// Capture config at registration time
|
|
409
|
+
// Check all possible IDs for backward compatibility and various installation methods
|
|
410
|
+
const entries = api.getConfig?.()?.plugins?.entries || {};
|
|
411
|
+
const entry = entries['openclaw-overlay']
|
|
412
|
+
|| entries['openclaw-overlay-plugin']
|
|
413
|
+
|| entries['bsv-overlay']
|
|
414
|
+
|| {};
|
|
415
|
+
// Merge: gateway-level api.config > nested entry.config > flat entry properties
|
|
410
416
|
const pluginConfig = { ...entry, ...(entry.config || {}), ...(api.config || {}) };
|
|
411
417
|
// Register the overlay agent tool
|
|
412
418
|
api.registerTool({
|
|
@@ -541,7 +547,7 @@ export default function register(api) {
|
|
|
541
547
|
});
|
|
542
548
|
// Register background relay service
|
|
543
549
|
api.registerService({
|
|
544
|
-
id: "
|
|
550
|
+
id: "openclaw-overlay-relay",
|
|
545
551
|
start: async () => {
|
|
546
552
|
try {
|
|
547
553
|
api.logger.info("Starting BSV overlay WebSocket relay...");
|
|
@@ -568,7 +574,7 @@ export default function register(api) {
|
|
|
568
574
|
});
|
|
569
575
|
// Register a skill-style wake handler
|
|
570
576
|
api.registerHook({
|
|
571
|
-
id: "
|
|
577
|
+
id: "openclaw-overlay-wake",
|
|
572
578
|
event: "gateway:start",
|
|
573
579
|
handler: async (ctx) => {
|
|
574
580
|
// Auto-check for registration on startup
|
|
@@ -576,8 +582,8 @@ export default function register(api) {
|
|
|
576
582
|
try {
|
|
577
583
|
const env = buildEnvironment(pluginConfig);
|
|
578
584
|
const cliPath = path.join(__dirname, 'dist', 'cli.js');
|
|
579
|
-
const regPath = path.join(process.env.HOME || '', '.openclaw', '
|
|
580
|
-
const onboardSentFile = path.join(process.env.HOME || '', '.openclaw', '
|
|
585
|
+
const regPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'registration.json');
|
|
586
|
+
const onboardSentFile = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'onboarding-sent.flag');
|
|
581
587
|
if (!fs.existsSync(regPath) && !fs.existsSync(onboardSentFile)) {
|
|
582
588
|
// Check if wallet exists
|
|
583
589
|
const walletPath = path.join(pluginConfig.walletDir || path.join(os.homedir(), '.openclaw', 'bsv-wallet'), 'wallet-identity.json');
|
|
@@ -598,7 +604,7 @@ export default function register(api) {
|
|
|
598
604
|
// Funded but not registered. Auto-register.
|
|
599
605
|
const regResult = await execFileAsync('node', [cliPath, 'register'], { env, timeout: 60000 });
|
|
600
606
|
if (parseCliOutput(regResult.stdout).success) {
|
|
601
|
-
ctx.logger.info('[
|
|
607
|
+
ctx.logger.info('[openclaw-overlay] Agent auto-registered on startup');
|
|
602
608
|
await autoAdvertiseServices(env, cliPath, ctx.logger);
|
|
603
609
|
}
|
|
604
610
|
}
|
|
@@ -606,7 +612,7 @@ export default function register(api) {
|
|
|
606
612
|
}
|
|
607
613
|
}
|
|
608
614
|
catch (err) {
|
|
609
|
-
api.log?.debug?.('[
|
|
615
|
+
api.log?.debug?.('[openclaw-overlay] Auto-setup/onboarding skipped:', err.message);
|
|
610
616
|
}
|
|
611
617
|
})();
|
|
612
618
|
}
|
|
@@ -669,13 +675,15 @@ export default function register(api) {
|
|
|
669
675
|
if (result.agents) {
|
|
670
676
|
console.log("\nAgents:");
|
|
671
677
|
result.agents.forEach((agent) => {
|
|
672
|
-
|
|
678
|
+
const name = agent.name || agent.agentName || 'Unknown Agent';
|
|
679
|
+
console.log(`- ${name} (${agent.identityKey.slice(0, 16)}...)`);
|
|
673
680
|
});
|
|
674
681
|
}
|
|
675
682
|
if (result.services) {
|
|
676
683
|
console.log("\nServices:");
|
|
677
684
|
result.services.forEach((service) => {
|
|
678
|
-
|
|
685
|
+
const name = service.name || service.agentName || 'Unknown Agent';
|
|
686
|
+
console.log(`- ${service.serviceId} - ${name} (${service.pricing?.amountSats || 0} sats) by ${service.identityKey.slice(0, 12)}`);
|
|
679
687
|
});
|
|
680
688
|
}
|
|
681
689
|
}
|
|
@@ -883,7 +891,7 @@ function validateConfirmToken(token, expectedAction) {
|
|
|
883
891
|
async function handleUnregister(params, env, cliPath) {
|
|
884
892
|
const { confirmToken } = params;
|
|
885
893
|
// Load current registration to show what will be deleted
|
|
886
|
-
const regPath = path.join(process.env.HOME || '', '.openclaw', '
|
|
894
|
+
const regPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'registration.json');
|
|
887
895
|
let registration = null;
|
|
888
896
|
try {
|
|
889
897
|
if (fs.existsSync(regPath)) {
|
|
@@ -1025,24 +1033,53 @@ async function handleDiscover(params, env, cliPath) {
|
|
|
1025
1033
|
return output.data;
|
|
1026
1034
|
}
|
|
1027
1035
|
async function handleBalance(env, cliPath) {
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1036
|
+
try {
|
|
1037
|
+
const result = await execFileAsync('node', [cliPath, 'balance'], { env });
|
|
1038
|
+
const output = parseCliOutput(result.stdout);
|
|
1039
|
+
if (!output.success) {
|
|
1040
|
+
throw new Error(output.error);
|
|
1041
|
+
}
|
|
1042
|
+
return output.data;
|
|
1043
|
+
}
|
|
1044
|
+
catch (error) {
|
|
1045
|
+
if (error.message?.includes('Wallet not initialized')) {
|
|
1046
|
+
return { walletBalance: 0, error: 'Not Initialized' };
|
|
1047
|
+
}
|
|
1048
|
+
throw new Error(`Balance check failed: ${error.message}`);
|
|
1032
1049
|
}
|
|
1033
|
-
return output.data;
|
|
1034
1050
|
}
|
|
1035
1051
|
async function handleStatus(env, cliPath) {
|
|
1036
1052
|
try {
|
|
1037
1053
|
// Get identity
|
|
1038
|
-
|
|
1039
|
-
|
|
1054
|
+
let identity = { data: { identityKey: 'Not Initialized' } };
|
|
1055
|
+
try {
|
|
1056
|
+
const identityResult = await execFileAsync('node', [cliPath, 'identity'], { env });
|
|
1057
|
+
identity = parseCliOutput(identityResult.stdout);
|
|
1058
|
+
}
|
|
1059
|
+
catch (err) {
|
|
1060
|
+
if (!err.message?.includes('Wallet not initialized'))
|
|
1061
|
+
throw err;
|
|
1062
|
+
}
|
|
1040
1063
|
// Get balance
|
|
1041
|
-
|
|
1042
|
-
|
|
1064
|
+
let balance = { data: { walletBalance: 0 } };
|
|
1065
|
+
try {
|
|
1066
|
+
const balanceResult = await execFileAsync('node', [cliPath, 'balance'], { env });
|
|
1067
|
+
balance = parseCliOutput(balanceResult.stdout);
|
|
1068
|
+
}
|
|
1069
|
+
catch (err) {
|
|
1070
|
+
if (!err.message?.includes('Wallet not initialized'))
|
|
1071
|
+
throw err;
|
|
1072
|
+
}
|
|
1043
1073
|
// Get services
|
|
1044
|
-
|
|
1045
|
-
|
|
1074
|
+
let services = { data: [] };
|
|
1075
|
+
try {
|
|
1076
|
+
const servicesResult = await execFileAsync('node', [cliPath, 'services'], { env });
|
|
1077
|
+
services = parseCliOutput(servicesResult.stdout);
|
|
1078
|
+
}
|
|
1079
|
+
catch (err) {
|
|
1080
|
+
if (!err.message?.includes('Wallet not initialized'))
|
|
1081
|
+
throw err;
|
|
1082
|
+
}
|
|
1046
1083
|
return {
|
|
1047
1084
|
identity: identity.data,
|
|
1048
1085
|
balance: balance.data,
|
|
@@ -1111,7 +1148,7 @@ async function handleImport(params, env, cliPath) {
|
|
|
1111
1148
|
throw new Error(`Import failed: ${output.error}`);
|
|
1112
1149
|
}
|
|
1113
1150
|
// Check if we should auto-register after successful import
|
|
1114
|
-
const regPath = path.join(process.env.HOME || '', '.openclaw', '
|
|
1151
|
+
const regPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'registration.json');
|
|
1115
1152
|
const isRegistered = fs.existsSync(regPath);
|
|
1116
1153
|
if (!isRegistered && output.data?.balance >= 1000) {
|
|
1117
1154
|
// Auto-register immediately after funding
|
|
@@ -1327,7 +1364,7 @@ async function handlePendingRequests(env, cliPath) {
|
|
|
1327
1364
|
if (!output.success)
|
|
1328
1365
|
throw new Error(`Queue check failed: ${output.error}`);
|
|
1329
1366
|
// Clear the alert file since we're checking now
|
|
1330
|
-
const alertPath = path.join(process.env.HOME || '', '.openclaw', '
|
|
1367
|
+
const alertPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'pending-alert.jsonl');
|
|
1331
1368
|
try {
|
|
1332
1369
|
if (fs.existsSync(alertPath))
|
|
1333
1370
|
fs.unlinkSync(alertPath);
|
|
@@ -1336,7 +1373,7 @@ async function handlePendingRequests(env, cliPath) {
|
|
|
1336
1373
|
return output.data;
|
|
1337
1374
|
}
|
|
1338
1375
|
function handleActivity() {
|
|
1339
|
-
const feedPath = path.join(process.env.HOME || '', '.openclaw', '
|
|
1376
|
+
const feedPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'activity-feed.jsonl');
|
|
1340
1377
|
if (!fs.existsSync(feedPath))
|
|
1341
1378
|
return { events: [], count: 0 };
|
|
1342
1379
|
const lines = fs.readFileSync(feedPath, 'utf-8').trim().split('\n').filter(Boolean);
|
|
@@ -1380,8 +1417,16 @@ function buildEnvironment(config) {
|
|
|
1380
1417
|
if (config.chaintracksUrl) {
|
|
1381
1418
|
env.BSV_CHAINTRACKS_URL = config.chaintracksUrl;
|
|
1382
1419
|
}
|
|
1420
|
+
if (config.arcUrl) {
|
|
1421
|
+
env.BSV_ARC_URL = config.arcUrl;
|
|
1422
|
+
}
|
|
1383
1423
|
// Set defaults
|
|
1384
1424
|
env.BSV_NETWORK = env.BSV_NETWORK || 'mainnet';
|
|
1425
|
+
if (!env.BSV_ARC_URL) {
|
|
1426
|
+
env.BSV_ARC_URL = env.BSV_NETWORK === 'testnet'
|
|
1427
|
+
? 'https://testnet.arc.gorillapool.io'
|
|
1428
|
+
: 'https://arc.gorillapool.io';
|
|
1429
|
+
}
|
|
1385
1430
|
if (config.agentName) {
|
|
1386
1431
|
env.AGENT_NAME = config.agentName;
|
|
1387
1432
|
}
|
package/dist/src/core/wallet.js
CHANGED
|
@@ -176,7 +176,11 @@ export class BSVAgentWallet {
|
|
|
176
176
|
// 3. Network services (ARC broadcasting, chain tracking, etc.)
|
|
177
177
|
const serviceOptions = Services.createDefaultOptions(chain);
|
|
178
178
|
const chaintracksUrl = process.env.BSV_CHAINTRACKS_URL || 'https://chaintracks-us-1.bsvb.tech';
|
|
179
|
+
const arcUrl = process.env.BSV_ARC_URL;
|
|
179
180
|
serviceOptions.chaintracks = new ChaintracksServiceClient(chain, chaintracksUrl);
|
|
181
|
+
if (arcUrl) {
|
|
182
|
+
serviceOptions.arcUrl = arcUrl;
|
|
183
|
+
}
|
|
180
184
|
serviceOptions.taalApiKey = taalApiKey;
|
|
181
185
|
const services = new Services(serviceOptions);
|
|
182
186
|
// 4. Background monitor
|
|
@@ -224,12 +224,23 @@ export async function cmdBaemailRefund(requestId) {
|
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
226
|
await tx.sign();
|
|
227
|
-
// Broadcast
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
227
|
+
// Broadcast using configured ARC/Arcade URL or fallback to WhatsOnChain
|
|
228
|
+
const arcUrl = process.env.BSV_ARC_URL;
|
|
229
|
+
let broadcastResp;
|
|
230
|
+
if (arcUrl) {
|
|
231
|
+
broadcastResp = await fetchWithTimeout(`${arcUrl.replace(/\/$/, '')}/v1/tx`, {
|
|
232
|
+
method: 'POST',
|
|
233
|
+
headers: { 'Content-Type': 'application/json' },
|
|
234
|
+
body: JSON.stringify({ rawTx: tx.toHex() }),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
broadcastResp = await fetchWithTimeout('https://api.whatsonchain.com/v1/bsv/main/tx/raw', {
|
|
239
|
+
method: 'POST',
|
|
240
|
+
headers: { 'Content-Type': 'application/json' },
|
|
241
|
+
body: JSON.stringify({ txhex: tx.toHex() }),
|
|
242
|
+
});
|
|
243
|
+
}
|
|
233
244
|
if (!broadcastResp.ok) {
|
|
234
245
|
const errBody = await broadcastResp.text();
|
|
235
246
|
return fail(`Broadcast failed: ${errBody}`);
|
|
@@ -16,7 +16,7 @@ export declare const WOC_API_KEY: string;
|
|
|
16
16
|
/** Overlay state directory for registration, services, etc. */
|
|
17
17
|
export declare const OVERLAY_STATE_DIR: string;
|
|
18
18
|
/** Protocol identifier for overlay transactions */
|
|
19
|
-
export declare const PROTOCOL_ID = "
|
|
19
|
+
export declare const PROTOCOL_ID = "clawdbot-overlay-v1";
|
|
20
20
|
/** Topic managers for overlay submissions */
|
|
21
21
|
export declare const TOPICS: {
|
|
22
22
|
readonly IDENTITY: "tm_openclaw_identity";
|
|
@@ -5,7 +5,7 @@ import path from 'node:path';
|
|
|
5
5
|
import os from 'node:os';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
// Auto-load .env from overlay state dir if it exists
|
|
8
|
-
const overlayEnvPath = path.join(os.homedir(), '.openclaw', '
|
|
8
|
+
const overlayEnvPath = path.join(os.homedir(), '.openclaw', 'openclaw-overlay', '.env');
|
|
9
9
|
try {
|
|
10
10
|
if (fs.existsSync(overlayEnvPath)) {
|
|
11
11
|
for (const line of fs.readFileSync(overlayEnvPath, 'utf-8').split('\n')) {
|
|
@@ -34,9 +34,9 @@ export const AGENT_DESCRIPTION = process.env.AGENT_DESCRIPTION ||
|
|
|
34
34
|
/** WhatsOnChain API key (optional, for rate limit bypass) */
|
|
35
35
|
export const WOC_API_KEY = process.env.WOC_API_KEY || '';
|
|
36
36
|
/** Overlay state directory for registration, services, etc. */
|
|
37
|
-
export const OVERLAY_STATE_DIR = path.join(os.homedir(), '.openclaw', '
|
|
37
|
+
export const OVERLAY_STATE_DIR = path.join(os.homedir(), '.openclaw', 'openclaw-overlay');
|
|
38
38
|
/** Protocol identifier for overlay transactions */
|
|
39
|
-
export const PROTOCOL_ID = '
|
|
39
|
+
export const PROTOCOL_ID = 'clawdbot-overlay-v1';
|
|
40
40
|
/** Topic managers for overlay submissions */
|
|
41
41
|
export const TOPICS = {
|
|
42
42
|
IDENTITY: 'tm_openclaw_identity',
|
|
@@ -28,7 +28,9 @@ export async function cmdDiscover(args) {
|
|
|
28
28
|
try {
|
|
29
29
|
const { data, txid } = await parseOverlayOutput(output.beef, output.outputIndex);
|
|
30
30
|
if (data?.type === 'identity') {
|
|
31
|
-
|
|
31
|
+
// Handle both 'name' and 'agentName' for backward compatibility
|
|
32
|
+
const name = data.name || data.agentName || 'Unknown Agent';
|
|
33
|
+
results.agents.push({ ...data, name, txid });
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
catch { /* ignore */ }
|