openclaw-overlay-plugin 0.7.52 → 0.7.54

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
@@ -74,6 +74,15 @@ The plugin needs the HTTP hooks endpoint enabled in your global `openclaw.json`
74
74
  }
75
75
  ```
76
76
 
77
+ ## Slash Commands (Autoreply)
78
+
79
+ You can interact with the overlay network directly from the chat using slash commands. These commands execute instantly and do not invoke the AI agent.
80
+
81
+ - `/overlay status` — Quick view of identity and balance.
82
+ - `/overlay balance` — Check wallet funding.
83
+ - `/overlay discover <serviceId>` — Find providers for a specific service.
84
+ - `/overlay onboard` — Trigger the onboarding check.
85
+
77
86
  ---
78
87
 
79
88
  ## AI Tool: `overlay`
package/dist/index.js CHANGED
@@ -7,17 +7,6 @@ import fs from 'node:fs';
7
7
  import { initializeServiceSystem, serviceManager } from './src/services/index.js';
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = path.dirname(__filename);
10
- /**
11
- * Helper to correctly locate the CLI script.
12
- * If running from dist/index.js, CLI is in ./src/cli.js
13
- * If running from index.ts, CLI is in ./dist/src/cli.js
14
- */
15
- function getCliPath() {
16
- const localCli = path.join(__dirname, 'src', 'cli.js');
17
- if (fs.existsSync(localCli))
18
- return localCli;
19
- return path.join(__dirname, 'dist', 'src', 'cli.js');
20
- }
21
10
  const execFileAsync = promisify(execFile);
22
11
  // Track background process for proper lifecycle management
23
12
  let backgroundProcess = null;
@@ -173,7 +162,7 @@ async function autoAdvertiseServices(env, cliPath, logger) {
173
162
  continue;
174
163
  try {
175
164
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
176
- const pluginConfig = config?.plugins?.entries?.['openclaw-overlay']?.config;
165
+ const pluginConfig = config?.plugins?.entries?.['openclaw-overlay-plugin']?.config || config?.plugins?.entries?.['openclaw-overlay-plugin'];
177
166
  if (pluginConfig?.services && Array.isArray(pluginConfig.services)) {
178
167
  servicesToAdvertise = pluginConfig.services;
179
168
  break;
@@ -419,18 +408,18 @@ export async function activate(api) {
419
408
  return register(api);
420
409
  }
421
410
  let isInitialized = false;
411
+ function getCliPath() {
412
+ // If we are already in the dist folder (running from compiled JS), don't add it again
413
+ const base = __dirname.endsWith('dist') ? __dirname : path.join(__dirname, 'dist');
414
+ return path.join(base, 'src', 'cli.js');
415
+ }
422
416
  export default function register(api) {
423
417
  if (isInitialized)
424
418
  return;
425
419
  isInitialized = true;
426
420
  // Capture config at registration time
427
- // Check all possible IDs for backward compatibility and various installation methods
428
421
  const entries = api.getConfig?.()?.plugins?.entries || {};
429
- const entry = entries['openclaw-overlay']
430
- || entries['openclaw-overlay-plugin']
431
- || entries['bsv-overlay']
432
- || {};
433
- // Merge: gateway-level api.config > nested entry.config > flat entry properties
422
+ const entry = entries['openclaw-overlay-plugin'] || entries['openclaw-overlay'] || entries['bsv-overlay-skill'] || {};
434
423
  const pluginConfig = { ...entry, ...(entry.config || {}), ...(api.config || {}) };
435
424
  // Register the overlay agent tool
436
425
  api.registerTool({
@@ -563,6 +552,44 @@ export default function register(api) {
563
552
  }
564
553
  }
565
554
  });
555
+ // Register the /overlay slash command for direct chat interaction (Autoreply)
556
+ api.registerCommand({
557
+ name: "overlay",
558
+ description: "BSV Overlay Marketplace commands",
559
+ acceptsArgs: true,
560
+ requireAuth: true,
561
+ handler: async (ctx) => {
562
+ try {
563
+ const args = ctx.args || [];
564
+ const action = args[0] || 'status';
565
+ // Map slash command args to tool params
566
+ const params = { action };
567
+ if (action === 'request' && args[1])
568
+ params.service = args[1];
569
+ if (action === 'discover' && args[1])
570
+ params.service = args[1];
571
+ if (action === 'pay' && args[1])
572
+ params.identityKey = args[1];
573
+ if (action === 'pay' && args[2])
574
+ params.sats = parseInt(args[2], 10);
575
+ const result = await executeOverlayAction(params, pluginConfig, api);
576
+ let text = `**Overlay: ${action.toUpperCase()}**\n\n`;
577
+ if (typeof result === 'string') {
578
+ text += result;
579
+ }
580
+ else if (result.message) {
581
+ text += result.message;
582
+ }
583
+ else {
584
+ text += JSON.stringify(result, null, 2);
585
+ }
586
+ return { text };
587
+ }
588
+ catch (error) {
589
+ return { text: `❌ Overlay Error: ${error.message}` };
590
+ }
591
+ }
592
+ });
566
593
  // Register background relay service
567
594
  api.registerService({
568
595
  id: "openclaw-overlay-relay",
@@ -571,13 +598,11 @@ export default function register(api) {
571
598
  api.logger.info("Starting BSV overlay WebSocket relay...");
572
599
  const env = buildEnvironment(pluginConfig);
573
600
  const cliPath = getCliPath();
574
- // Initialize the service system if available
575
601
  try {
576
602
  await initializeServiceSystem();
577
603
  }
578
604
  catch { }
579
605
  startBackgroundService(env, cliPath, api.logger);
580
- // Start auto-import
581
606
  startAutoImport(env, cliPath, api.logger);
582
607
  // Auto-check for registration on startup
583
608
  (async () => {
@@ -587,11 +612,9 @@ export default function register(api) {
587
612
  if (!fs.existsSync(regPath) && !fs.existsSync(onboardSentFile)) {
588
613
  const walletPath = path.join(pluginConfig.walletDir || path.join(os.homedir(), '.openclaw', 'bsv-wallet'), 'wallet-identity.json');
589
614
  if (fs.existsSync(walletPath)) {
590
- // Wallet exists but not registered.
591
615
  const balResult = await execFileAsync('node', [cliPath, 'balance'], { env });
592
616
  const balance = parseCliOutput(balResult.stdout);
593
617
  if ((balance.data?.walletBalance || 0) >= 1000) {
594
- // Funded but not registered. Auto-register.
595
618
  const regResult = await execFileAsync('node', [cliPath, 'register'], { env, timeout: 60000 });
596
619
  if (parseCliOutput(regResult.stdout).success) {
597
620
  api.logger.info('[openclaw-overlay] Agent auto-registered on startup');
@@ -734,7 +757,7 @@ export default function register(api) {
734
757
  console.error("Error:", error.message);
735
758
  }
736
759
  });
737
- });
760
+ }, { commands: ["overlay"] });
738
761
  }
739
762
  async function executeOverlayAction(params, config, api) {
740
763
  const { action } = params;
@@ -801,7 +824,6 @@ async function handleServiceRequest(params, env, cliPath, config, api) {
801
824
  if (!discoverOutput.success) {
802
825
  throw new Error(`Discovery failed: ${discoverOutput.error}`);
803
826
  }
804
- // FIX: Use discoverOutput.data.services instead of treating data as flat array
805
827
  const providers = discoverOutput.data.services;
806
828
  if (!providers || providers.length === 0) {
807
829
  throw new Error(`No providers found for service: ${service}`);
@@ -822,7 +844,7 @@ async function handleServiceRequest(params, env, cliPath, config, api) {
822
844
  }
823
845
  externalProviders = targeted;
824
846
  }
825
- // 3. Sort by price - FIX: Use pricing.amountSats instead of pricingSats
847
+ // 3. Sort by price
826
848
  externalProviders.sort((a, b) => (a.pricing?.amountSats || 0) - (b.pricing?.amountSats || 0));
827
849
  const bestProvider = externalProviders[0];
828
850
  const price = bestProvider.pricing?.amountSats || 0;
@@ -849,10 +871,6 @@ async function handleServiceRequest(params, env, cliPath, config, api) {
849
871
  if (!requestOutput.success) {
850
872
  throw new Error(`Service request failed: ${requestOutput.error}`);
851
873
  }
852
- // 7. Return immediately — no polling.
853
- // The WebSocket background service handles incoming responses
854
- // asynchronously and wakes the agent via /hooks/agent when a
855
- // response arrives. This avoids blocking for up to 120s.
856
874
  recordSpend(walletDir, price, service, bestProvider.name);
857
875
  writeActivityEvent({ type: 'outgoing_payment', emoji: '💸', sats: price, service, provider: bestProvider.name, message: `Paid ${price} sats to ${bestProvider.name} for ${service}` });
858
876
  return {
@@ -1149,7 +1167,7 @@ async function handleImport(params, env, cliPath) {
1149
1167
  // Check if we should auto-register after successful import
1150
1168
  const regPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'registration.json');
1151
1169
  const isRegistered = fs.existsSync(regPath);
1152
- if (!isRegistered && output.data?.balance >= 1000) {
1170
+ if (!isRegistered && (output.data?.balance || 0) >= 1000) {
1153
1171
  // Auto-register immediately after funding
1154
1172
  try {
1155
1173
  const regResult = await execFileAsync('node', [cliPath, 'register'], { env, timeout: 60000 });
@@ -1281,13 +1299,11 @@ async function handleRefund(params, env, cliPath) {
1281
1299
  async function handleOnboard(params, env, cliPath) {
1282
1300
  const { agentName, agentDescription } = params;
1283
1301
  const steps = [];
1284
- // Apply agent name/description to env if provided
1285
1302
  const onboardEnv = { ...env };
1286
1303
  if (agentName)
1287
1304
  onboardEnv.AGENT_NAME = agentName;
1288
1305
  if (agentDescription)
1289
1306
  onboardEnv.AGENT_DESCRIPTION = agentDescription;
1290
- // Step 1: Setup wallet
1291
1307
  try {
1292
1308
  const setup = await execFileAsync('node', [cliPath, 'setup'], { env: onboardEnv });
1293
1309
  const setupOutput = parseCliOutput(setup.stdout);
@@ -1297,7 +1313,6 @@ async function handleOnboard(params, env, cliPath) {
1297
1313
  steps.push({ step: 'setup', success: false, error: err.message });
1298
1314
  return { steps, nextStep: 'Fix wallet setup error and try again' };
1299
1315
  }
1300
- // Step 2: Get address
1301
1316
  try {
1302
1317
  const addr = await execFileAsync('node', [cliPath, 'address'], { env: onboardEnv });
1303
1318
  const addrOutput = parseCliOutput(addr.stdout);
@@ -1306,7 +1321,6 @@ async function handleOnboard(params, env, cliPath) {
1306
1321
  catch (err) {
1307
1322
  steps.push({ step: 'address', success: false, error: err.message });
1308
1323
  }
1309
- // Step 3: Check balance
1310
1324
  try {
1311
1325
  const bal = await execFileAsync('node', [cliPath, 'balance'], { env: onboardEnv });
1312
1326
  const balOutput = parseCliOutput(bal.stdout);
@@ -1323,7 +1337,6 @@ async function handleOnboard(params, env, cliPath) {
1323
1337
  catch (err) {
1324
1338
  steps.push({ step: 'balance', success: false, error: err.message });
1325
1339
  }
1326
- // Step 4: Register
1327
1340
  try {
1328
1341
  const reg = await execFileAsync('node', [cliPath, 'register'], { env: onboardEnv, timeout: 60000 });
1329
1342
  const regOutput = parseCliOutput(reg.stdout);
@@ -1350,7 +1363,6 @@ async function handleOnboard(params, env, cliPath) {
1350
1363
  };
1351
1364
  }
1352
1365
  async function handlePendingRequests(env, cliPath) {
1353
- // Clean up old queue entries before checking pending requests
1354
1366
  try {
1355
1367
  const { cleanupServiceQueue } = await import('./src/scripts/utils/storage.js');
1356
1368
  cleanupServiceQueue();
@@ -1362,7 +1374,6 @@ async function handlePendingRequests(env, cliPath) {
1362
1374
  const output = parseCliOutput(result.stdout);
1363
1375
  if (!output.success)
1364
1376
  throw new Error(`Queue check failed: ${output.error}`);
1365
- // Clear the alert file since we're checking now
1366
1377
  const alertPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'pending-alert.jsonl');
1367
1378
  try {
1368
1379
  if (fs.existsSync(alertPath))
@@ -1382,7 +1393,6 @@ function handleActivity() {
1382
1393
  catch {
1383
1394
  return null;
1384
1395
  } }).filter(Boolean);
1385
- // Clear the feed after reading
1386
1396
  fs.writeFileSync(feedPath, '');
1387
1397
  return { events, count: events.length };
1388
1398
  }
@@ -1397,7 +1407,6 @@ async function handleFulfill(params, env, cliPath) {
1397
1407
  const output = parseCliOutput(cliResult.stdout);
1398
1408
  if (!output.success)
1399
1409
  throw new Error(`Fulfill failed: ${output.error}`);
1400
- // Clean up the request ID from tracking since it's now fulfilled
1401
1410
  wokenRequests.delete(requestId);
1402
1411
  writeActivityEvent({ type: 'service_fulfilled', emoji: '✅', serviceId, recipientKey: recipientKey?.slice(0, 16), message: `Fulfilled ${serviceId} request — response sent` });
1403
1412
  return output.data;
@@ -1419,7 +1428,6 @@ function buildEnvironment(config) {
1419
1428
  if (config.arcUrl) {
1420
1429
  env.BSV_ARC_URL = config.arcUrl;
1421
1430
  }
1422
- // Set defaults
1423
1431
  env.BSV_NETWORK = env.BSV_NETWORK || 'mainnet';
1424
1432
  if (!env.BSV_ARC_URL) {
1425
1433
  env.BSV_ARC_URL = env.BSV_NETWORK === 'testnet'
@@ -1438,7 +1446,7 @@ function buildEnvironment(config) {
1438
1446
  else if (!env.AGENT_DESCRIPTION) {
1439
1447
  env.AGENT_DESCRIPTION = 'AI agent on the OpenClaw Overlay Network. Offers services for BSV micropayments.';
1440
1448
  }
1441
- env.AGENT_ROUTED = 'true'; // Route service requests through the agent
1449
+ env.AGENT_ROUTED = 'true';
1442
1450
  return env;
1443
1451
  }
1444
1452
  function parseCliOutput(stdout) {
@@ -1450,4 +1458,3 @@ function parseCliOutput(stdout) {
1450
1458
  throw new Error(`Failed to parse CLI output: ${error.message}`);
1451
1459
  }
1452
1460
  }
1453
- // sleep() removed — no longer needed since polling loop was removed
package/index.ts CHANGED
@@ -8,17 +8,6 @@ import { initializeServiceSystem, serviceManager } from './src/services/index.js
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = path.dirname(__filename);
10
10
 
11
- /**
12
- * Helper to correctly locate the CLI script.
13
- * If running from dist/index.js, CLI is in ./src/cli.js
14
- * If running from index.ts, CLI is in ./dist/src/cli.js
15
- */
16
- function getCliPath(): string {
17
- const localCli = path.join(__dirname, 'src', 'cli.js');
18
- if (fs.existsSync(localCli)) return localCli;
19
- return path.join(__dirname, 'dist', 'src', 'cli.js');
20
- }
21
-
22
11
  const execFileAsync = promisify(execFile);
23
12
 
24
13
  // Track background process for proper lifecycle management
@@ -190,7 +179,7 @@ async function autoAdvertiseServices(env: any, cliPath: string, logger: any) {
190
179
  if (!fs.existsSync(configPath)) continue;
191
180
  try {
192
181
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
193
- const pluginConfig = config?.plugins?.entries?.['openclaw-overlay']?.config;
182
+ const pluginConfig = config?.plugins?.entries?.['openclaw-overlay-plugin']?.config || config?.plugins?.entries?.['openclaw-overlay-plugin'];
194
183
  if (pluginConfig?.services && Array.isArray(pluginConfig.services)) {
195
184
  servicesToAdvertise = pluginConfig.services;
196
185
  break;
@@ -464,19 +453,19 @@ export async function activate(api: any) {
464
453
 
465
454
  let isInitialized = false;
466
455
 
456
+ function getCliPath() {
457
+ // If we are already in the dist folder (running from compiled JS), don't add it again
458
+ const base = __dirname.endsWith('dist') ? __dirname : path.join(__dirname, 'dist');
459
+ return path.join(base, 'src', 'cli.js');
460
+ }
461
+
467
462
  export default function register(api: any) {
468
463
  if (isInitialized) return;
469
464
  isInitialized = true;
470
465
 
471
466
  // Capture config at registration time
472
- // Check all possible IDs for backward compatibility and various installation methods
473
467
  const entries = api.getConfig?.()?.plugins?.entries || {};
474
- const entry = entries['openclaw-overlay']
475
- || entries['openclaw-overlay-plugin']
476
- || entries['bsv-overlay']
477
- || {};
478
-
479
- // Merge: gateway-level api.config > nested entry.config > flat entry properties
468
+ const entry = entries['openclaw-overlay-plugin'] || entries['openclaw-overlay'] || entries['bsv-overlay-skill'] || {};
480
469
  const pluginConfig = { ...entry, ...(entry.config || {}), ...(api.config || {}) };
481
470
 
482
471
  // Register the overlay agent tool
@@ -610,6 +599,43 @@ export default function register(api: any) {
610
599
  }
611
600
  });
612
601
 
602
+ // Register the /overlay slash command for direct chat interaction (Autoreply)
603
+ api.registerCommand({
604
+ name: "overlay",
605
+ description: "BSV Overlay Marketplace commands",
606
+ acceptsArgs: true,
607
+ requireAuth: true,
608
+ handler: async (ctx: any) => {
609
+ try {
610
+ const args = ctx.args || [];
611
+ const action = args[0] || 'status';
612
+
613
+ // Map slash command args to tool params
614
+ const params: any = { action };
615
+
616
+ if (action === 'request' && args[1]) params.service = args[1];
617
+ if (action === 'discover' && args[1]) params.service = args[1];
618
+ if (action === 'pay' && args[1]) params.identityKey = args[1];
619
+ if (action === 'pay' && args[2]) params.sats = parseInt(args[2], 10);
620
+
621
+ const result = await executeOverlayAction(params, pluginConfig, api);
622
+
623
+ let text = `**Overlay: ${action.toUpperCase()}**\n\n`;
624
+ if (typeof result === 'string') {
625
+ text += result;
626
+ } else if (result.message) {
627
+ text += result.message;
628
+ } else {
629
+ text += JSON.stringify(result, null, 2);
630
+ }
631
+
632
+ return { text };
633
+ } catch (error: any) {
634
+ return { text: `❌ Overlay Error: ${error.message}` };
635
+ }
636
+ }
637
+ });
638
+
613
639
  // Register background relay service
614
640
  api.registerService({
615
641
  id: "openclaw-overlay-relay",
@@ -619,14 +645,11 @@ export default function register(api: any) {
619
645
  const env = buildEnvironment(pluginConfig);
620
646
  const cliPath = getCliPath();
621
647
 
622
- // Initialize the service system if available
623
648
  try {
624
649
  await initializeServiceSystem();
625
650
  } catch {}
626
651
 
627
652
  startBackgroundService(env, cliPath, api.logger);
628
-
629
- // Start auto-import
630
653
  startAutoImport(env, cliPath, api.logger);
631
654
 
632
655
  // Auto-check for registration on startup
@@ -639,12 +662,10 @@ export default function register(api: any) {
639
662
  const walletPath = path.join(pluginConfig.walletDir || path.join(os.homedir(), '.openclaw', 'bsv-wallet'), 'wallet-identity.json');
640
663
 
641
664
  if (fs.existsSync(walletPath)) {
642
- // Wallet exists but not registered.
643
665
  const balResult = await execFileAsync('node', [cliPath, 'balance'], { env });
644
666
  const balance = parseCliOutput(balResult.stdout);
645
667
 
646
668
  if ((balance.data?.walletBalance || 0) >= 1000) {
647
- // Funded but not registered. Auto-register.
648
669
  const regResult = await execFileAsync('node', [cliPath, 'register'], { env, timeout: 60000 });
649
670
  if (parseCliOutput(regResult.stdout).success) {
650
671
  api.logger.info('[openclaw-overlay] Agent auto-registered on startup');
@@ -789,7 +810,7 @@ export default function register(api: any) {
789
810
  console.error("Error:", error.message);
790
811
  }
791
812
  });
792
- });
813
+ }, { commands: ["overlay"] });
793
814
  }
794
815
 
795
816
  async function executeOverlayAction(params: any, config: any, api: any) {
@@ -885,7 +906,6 @@ async function handleServiceRequest(params: any, env: any, cliPath: string, conf
885
906
  throw new Error(`Discovery failed: ${discoverOutput.error}`);
886
907
  }
887
908
 
888
- // FIX: Use discoverOutput.data.services instead of treating data as flat array
889
909
  const providers = discoverOutput.data.services;
890
910
  if (!providers || providers.length === 0) {
891
911
  throw new Error(`No providers found for service: ${service}`);
@@ -910,7 +930,7 @@ async function handleServiceRequest(params: any, env: any, cliPath: string, conf
910
930
  externalProviders = targeted;
911
931
  }
912
932
 
913
- // 3. Sort by price - FIX: Use pricing.amountSats instead of pricingSats
933
+ // 3. Sort by price
914
934
  externalProviders.sort((a: any, b: any) => (a.pricing?.amountSats || 0) - (b.pricing?.amountSats || 0));
915
935
 
916
936
  const bestProvider = externalProviders[0];
@@ -946,10 +966,6 @@ async function handleServiceRequest(params: any, env: any, cliPath: string, conf
946
966
  throw new Error(`Service request failed: ${requestOutput.error}`);
947
967
  }
948
968
 
949
- // 7. Return immediately — no polling.
950
- // The WebSocket background service handles incoming responses
951
- // asynchronously and wakes the agent via /hooks/agent when a
952
- // response arrives. This avoids blocking for up to 120s.
953
969
  recordSpend(walletDir, price, service, bestProvider.name);
954
970
  writeActivityEvent({ type: 'outgoing_payment', emoji: '💸', sats: price, service, provider: bestProvider.name, message: `Paid ${price} sats to ${bestProvider.name} for ${service}` });
955
971
 
@@ -1294,7 +1310,7 @@ async function handleImport(params: any, env: any, cliPath: string) {
1294
1310
  const regPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'registration.json');
1295
1311
  const isRegistered = fs.existsSync(regPath);
1296
1312
 
1297
- if (!isRegistered && output.data?.balance >= 1000) {
1313
+ if (!isRegistered && (output.data?.balance || 0) >= 1000) {
1298
1314
  // Auto-register immediately after funding
1299
1315
  try {
1300
1316
  const regResult = await execFileAsync('node', [cliPath, 'register'], { env, timeout: 60000 });
@@ -1464,12 +1480,10 @@ async function handleOnboard(params: any, env: any, cliPath: string) {
1464
1480
  const { agentName, agentDescription } = params;
1465
1481
  const steps = [];
1466
1482
 
1467
- // Apply agent name/description to env if provided
1468
1483
  const onboardEnv = { ...env };
1469
1484
  if (agentName) onboardEnv.AGENT_NAME = agentName;
1470
1485
  if (agentDescription) onboardEnv.AGENT_DESCRIPTION = agentDescription;
1471
1486
 
1472
- // Step 1: Setup wallet
1473
1487
  try {
1474
1488
  const setup = await execFileAsync('node', [cliPath, 'setup'], { env: onboardEnv });
1475
1489
  const setupOutput = parseCliOutput(setup.stdout);
@@ -1479,7 +1493,6 @@ async function handleOnboard(params: any, env: any, cliPath: string) {
1479
1493
  return { steps, nextStep: 'Fix wallet setup error and try again' };
1480
1494
  }
1481
1495
 
1482
- // Step 2: Get address
1483
1496
  try {
1484
1497
  const addr = await execFileAsync('node', [cliPath, 'address'], { env: onboardEnv });
1485
1498
  const addrOutput = parseCliOutput(addr.stdout);
@@ -1488,7 +1501,6 @@ async function handleOnboard(params: any, env: any, cliPath: string) {
1488
1501
  steps.push({ step: 'address', success: false, error: err.message });
1489
1502
  }
1490
1503
 
1491
- // Step 3: Check balance
1492
1504
  try {
1493
1505
  const bal = await execFileAsync('node', [cliPath, 'balance'], { env: onboardEnv });
1494
1506
  const balOutput = parseCliOutput(bal.stdout);
@@ -1506,7 +1518,6 @@ async function handleOnboard(params: any, env: any, cliPath: string) {
1506
1518
  steps.push({ step: 'balance', success: false, error: err.message });
1507
1519
  }
1508
1520
 
1509
- // Step 4: Register
1510
1521
  try {
1511
1522
  const reg = await execFileAsync('node', [cliPath, 'register'], { env: onboardEnv, timeout: 60000 });
1512
1523
  const regOutput = parseCliOutput(reg.stdout);
@@ -1534,7 +1545,6 @@ async function handleOnboard(params: any, env: any, cliPath: string) {
1534
1545
  }
1535
1546
 
1536
1547
  async function handlePendingRequests(env: any, cliPath: string) {
1537
- // Clean up old queue entries before checking pending requests
1538
1548
  try {
1539
1549
  const { cleanupServiceQueue } = await import('./src/scripts/utils/storage.js');
1540
1550
  cleanupServiceQueue();
@@ -1546,7 +1556,6 @@ async function handlePendingRequests(env: any, cliPath: string) {
1546
1556
  const output = parseCliOutput(result.stdout);
1547
1557
  if (!output.success) throw new Error(`Queue check failed: ${output.error}`);
1548
1558
 
1549
- // Clear the alert file since we're checking now
1550
1559
  const alertPath = path.join(process.env.HOME || '', '.openclaw', 'openclaw-overlay', 'pending-alert.jsonl');
1551
1560
  try { if (fs.existsSync(alertPath)) fs.unlinkSync(alertPath); } catch {}
1552
1561
 
@@ -1560,7 +1569,6 @@ function handleActivity() {
1560
1569
  const lines = fs.readFileSync(feedPath, 'utf-8')?.trim().split('\n').filter(Boolean);
1561
1570
  const events = lines.map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
1562
1571
 
1563
- // Clear the feed after reading
1564
1572
  fs.writeFileSync(feedPath, '');
1565
1573
 
1566
1574
  return { events, count: events.length };
@@ -1578,7 +1586,6 @@ async function handleFulfill(params: any, env: any, cliPath: string) {
1578
1586
  const output = parseCliOutput(cliResult.stdout);
1579
1587
  if (!output.success) throw new Error(`Fulfill failed: ${output.error}`);
1580
1588
 
1581
- // Clean up the request ID from tracking since it's now fulfilled
1582
1589
  wokenRequests.delete(requestId);
1583
1590
 
1584
1591
  writeActivityEvent({ type: 'service_fulfilled', emoji: '✅', serviceId, recipientKey: recipientKey?.slice(0, 16), message: `Fulfilled ${serviceId} request — response sent` });
@@ -1604,7 +1611,6 @@ function buildEnvironment(config: any) {
1604
1611
  env.BSV_ARC_URL = config.arcUrl;
1605
1612
  }
1606
1613
 
1607
- // Set defaults
1608
1614
  env.BSV_NETWORK = env.BSV_NETWORK || 'mainnet';
1609
1615
 
1610
1616
  if (!env.BSV_ARC_URL) {
@@ -1622,7 +1628,7 @@ function buildEnvironment(config: any) {
1622
1628
  } else if (!env.AGENT_DESCRIPTION) {
1623
1629
  env.AGENT_DESCRIPTION = 'AI agent on the OpenClaw Overlay Network. Offers services for BSV micropayments.';
1624
1630
  }
1625
- env.AGENT_ROUTED = 'true'; // Route service requests through the agent
1631
+ env.AGENT_ROUTED = 'true';
1626
1632
 
1627
1633
  return env;
1628
1634
  }
@@ -1635,5 +1641,3 @@ function parseCliOutput(stdout: any) {
1635
1641
  throw new Error(`Failed to parse CLI output: ${error.message}`);
1636
1642
  }
1637
1643
  }
1638
-
1639
- // sleep() removed — no longer needed since polling loop was removed
@@ -6,9 +6,24 @@
6
6
  "skills": [
7
7
  "./SKILL.md"
8
8
  ],
9
+ "commands": [
10
+ {
11
+ "name": "overlay",
12
+ "description": "BSV Overlay Network management",
13
+ "isAutoreply": true
14
+ }
15
+ ],
16
+ "contracts": {
17
+ "tools": [
18
+ {
19
+ "name": "overlay",
20
+ "description": "Access the BSV agent marketplace - discover agents and exchange BSV micropayments for services"
21
+ }
22
+ ]
23
+ },
9
24
  "configSchema": {
10
25
  "type": "object",
11
- "additionalProperties": false,
26
+ "additionalProperties": true,
12
27
  "properties": {
13
28
  "overlayUrl": {
14
29
  "type": "string",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-overlay-plugin",
3
- "version": "0.7.52",
3
+ "version": "0.7.54",
4
4
  "description": "Openclaw BSV Overlay — agent discovery, service marketplace, and micropayments on the BSV blockchain",
5
5
  "publishConfig": {
6
6
  "access": "public"