openclaw-overlay-plugin 0.8.15 → 0.8.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 (189) hide show
  1. package/dist/index.js +6705 -326
  2. package/dist/index.js.map +7 -0
  3. package/dist/src/cli.js +7498 -11
  4. package/dist/src/cli.js.map +7 -0
  5. package/openclaw.plugin.json +1 -1
  6. package/package.json +6 -6
  7. package/src/scripts/messaging/handlers.ts +1 -1
  8. package/src/scripts/overlay/advertisement.ts +1 -1
  9. package/src/scripts/overlay/registration.ts +1 -1
  10. package/src/scripts/overlay/services.ts +1 -1
  11. package/src/scripts/overlay/transaction.ts +1 -1
  12. package/src/scripts/payment/build.ts +1 -1
  13. package/src/scripts/payment/commands.ts +1 -1
  14. package/src/scripts/wallet/balance.ts +1 -1
  15. package/src/scripts/wallet/setup.ts +1 -1
  16. package/src/test/identity-consistency.test.ts +1 -1
  17. package/src/test/wallet.test.ts +1 -2
  18. package/dist/index.d.ts +0 -9
  19. package/dist/src/cli-main.d.ts +0 -7
  20. package/dist/src/cli-main.js +0 -202
  21. package/dist/src/cli.d.ts +0 -8
  22. package/dist/src/compatibility.test.d.ts +0 -4
  23. package/dist/src/compatibility.test.js +0 -41
  24. package/dist/src/core/config.d.ts +0 -11
  25. package/dist/src/core/config.js +0 -15
  26. package/dist/src/core/index.d.ts +0 -25
  27. package/dist/src/core/index.js +0 -26
  28. package/dist/src/core/payment.d.ts +0 -16
  29. package/dist/src/core/payment.js +0 -94
  30. package/dist/src/core/types.d.ts +0 -94
  31. package/dist/src/core/types.js +0 -4
  32. package/dist/src/core/verify.d.ts +0 -28
  33. package/dist/src/core/verify.js +0 -104
  34. package/dist/src/core/wallet.d.ts +0 -105
  35. package/dist/src/core/wallet.js +0 -256
  36. package/dist/src/scripts/baemail/commands.d.ts +0 -35
  37. package/dist/src/scripts/baemail/commands.js +0 -282
  38. package/dist/src/scripts/baemail/handler.d.ts +0 -36
  39. package/dist/src/scripts/baemail/handler.js +0 -284
  40. package/dist/src/scripts/baemail/index.d.ts +0 -5
  41. package/dist/src/scripts/baemail/index.js +0 -5
  42. package/dist/src/scripts/config.d.ts +0 -52
  43. package/dist/src/scripts/config.js +0 -75
  44. package/dist/src/scripts/index.d.ts +0 -7
  45. package/dist/src/scripts/index.js +0 -7
  46. package/dist/src/scripts/messaging/connect.d.ts +0 -8
  47. package/dist/src/scripts/messaging/connect.js +0 -168
  48. package/dist/src/scripts/messaging/handlers.d.ts +0 -21
  49. package/dist/src/scripts/messaging/handlers.js +0 -334
  50. package/dist/src/scripts/messaging/inbox.d.ts +0 -11
  51. package/dist/src/scripts/messaging/inbox.js +0 -51
  52. package/dist/src/scripts/messaging/index.d.ts +0 -8
  53. package/dist/src/scripts/messaging/index.js +0 -8
  54. package/dist/src/scripts/messaging/poll.d.ts +0 -7
  55. package/dist/src/scripts/messaging/poll.js +0 -52
  56. package/dist/src/scripts/messaging/send.d.ts +0 -7
  57. package/dist/src/scripts/messaging/send.js +0 -43
  58. package/dist/src/scripts/output.d.ts +0 -13
  59. package/dist/src/scripts/output.js +0 -28
  60. package/dist/src/scripts/overlay/advertisement.d.ts +0 -16
  61. package/dist/src/scripts/overlay/advertisement.js +0 -122
  62. package/dist/src/scripts/overlay/discover.d.ts +0 -7
  63. package/dist/src/scripts/overlay/discover.js +0 -74
  64. package/dist/src/scripts/overlay/index.d.ts +0 -7
  65. package/dist/src/scripts/overlay/index.js +0 -7
  66. package/dist/src/scripts/overlay/registration.d.ts +0 -19
  67. package/dist/src/scripts/overlay/registration.js +0 -176
  68. package/dist/src/scripts/overlay/services.d.ts +0 -29
  69. package/dist/src/scripts/overlay/services.js +0 -167
  70. package/dist/src/scripts/overlay/transaction.d.ts +0 -42
  71. package/dist/src/scripts/overlay/transaction.js +0 -103
  72. package/dist/src/scripts/payment/build.d.ts +0 -24
  73. package/dist/src/scripts/payment/build.js +0 -54
  74. package/dist/src/scripts/payment/commands.d.ts +0 -15
  75. package/dist/src/scripts/payment/commands.js +0 -73
  76. package/dist/src/scripts/payment/index.d.ts +0 -6
  77. package/dist/src/scripts/payment/index.js +0 -6
  78. package/dist/src/scripts/payment/types.d.ts +0 -56
  79. package/dist/src/scripts/payment/types.js +0 -4
  80. package/dist/src/scripts/services/index.d.ts +0 -6
  81. package/dist/src/scripts/services/index.js +0 -6
  82. package/dist/src/scripts/services/queue.d.ts +0 -11
  83. package/dist/src/scripts/services/queue.js +0 -28
  84. package/dist/src/scripts/services/request.d.ts +0 -7
  85. package/dist/src/scripts/services/request.js +0 -82
  86. package/dist/src/scripts/services/respond.d.ts +0 -11
  87. package/dist/src/scripts/services/respond.js +0 -132
  88. package/dist/src/scripts/types.d.ts +0 -107
  89. package/dist/src/scripts/types.js +0 -4
  90. package/dist/src/scripts/utils/index.d.ts +0 -6
  91. package/dist/src/scripts/utils/index.js +0 -6
  92. package/dist/src/scripts/utils/merkle.d.ts +0 -12
  93. package/dist/src/scripts/utils/merkle.js +0 -47
  94. package/dist/src/scripts/utils/storage.d.ts +0 -66
  95. package/dist/src/scripts/utils/storage.js +0 -211
  96. package/dist/src/scripts/utils/woc.d.ts +0 -26
  97. package/dist/src/scripts/utils/woc.js +0 -91
  98. package/dist/src/scripts/wallet/balance.d.ts +0 -22
  99. package/dist/src/scripts/wallet/balance.js +0 -240
  100. package/dist/src/scripts/wallet/identity.d.ts +0 -71
  101. package/dist/src/scripts/wallet/identity.js +0 -152
  102. package/dist/src/scripts/wallet/index.d.ts +0 -6
  103. package/dist/src/scripts/wallet/index.js +0 -6
  104. package/dist/src/scripts/wallet/setup.d.ts +0 -19
  105. package/dist/src/scripts/wallet/setup.js +0 -119
  106. package/dist/src/scripts/x-verification/commands.d.ts +0 -27
  107. package/dist/src/scripts/x-verification/commands.js +0 -222
  108. package/dist/src/scripts/x-verification/index.d.ts +0 -4
  109. package/dist/src/scripts/x-verification/index.js +0 -4
  110. package/dist/src/services/built-in/api-proxy/index.d.ts +0 -6
  111. package/dist/src/services/built-in/api-proxy/index.js +0 -23
  112. package/dist/src/services/built-in/code-develop/index.d.ts +0 -6
  113. package/dist/src/services/built-in/code-develop/index.js +0 -23
  114. package/dist/src/services/built-in/code-review/index.d.ts +0 -10
  115. package/dist/src/services/built-in/code-review/index.js +0 -51
  116. package/dist/src/services/built-in/image-analysis/index.d.ts +0 -6
  117. package/dist/src/services/built-in/image-analysis/index.js +0 -33
  118. package/dist/src/services/built-in/memory-store/index.d.ts +0 -6
  119. package/dist/src/services/built-in/memory-store/index.js +0 -22
  120. package/dist/src/services/built-in/roulette/index.d.ts +0 -6
  121. package/dist/src/services/built-in/roulette/index.js +0 -27
  122. package/dist/src/services/built-in/summarize/index.d.ts +0 -6
  123. package/dist/src/services/built-in/summarize/index.js +0 -21
  124. package/dist/src/services/built-in/tell-joke/handler.d.ts +0 -7
  125. package/dist/src/services/built-in/tell-joke/handler.js +0 -122
  126. package/dist/src/services/built-in/tell-joke/index.d.ts +0 -9
  127. package/dist/src/services/built-in/tell-joke/index.js +0 -31
  128. package/dist/src/services/built-in/translate/index.d.ts +0 -6
  129. package/dist/src/services/built-in/translate/index.js +0 -21
  130. package/dist/src/services/built-in/web-research/index.d.ts +0 -9
  131. package/dist/src/services/built-in/web-research/index.js +0 -51
  132. package/dist/src/services/index.d.ts +0 -13
  133. package/dist/src/services/index.js +0 -14
  134. package/dist/src/services/loader.d.ts +0 -77
  135. package/dist/src/services/loader.js +0 -292
  136. package/dist/src/services/manager.d.ts +0 -86
  137. package/dist/src/services/manager.js +0 -255
  138. package/dist/src/services/registry.d.ts +0 -98
  139. package/dist/src/services/registry.js +0 -204
  140. package/dist/src/services/types.d.ts +0 -230
  141. package/dist/src/services/types.js +0 -30
  142. package/dist/src/test/cli.test.d.ts +0 -7
  143. package/dist/src/test/cli.test.js +0 -330
  144. package/dist/src/test/comprehensive-overlay.test.d.ts +0 -13
  145. package/dist/src/test/comprehensive-overlay.test.js +0 -593
  146. package/dist/src/test/identity-consistency.test.d.ts +0 -6
  147. package/dist/src/test/identity-consistency.test.js +0 -60
  148. package/dist/src/test/key-derivation.test.d.ts +0 -12
  149. package/dist/src/test/key-derivation.test.js +0 -86
  150. package/dist/src/test/network-address.test.d.ts +0 -9
  151. package/dist/src/test/network-address.test.js +0 -37
  152. package/dist/src/test/overlay-submit.test.d.ts +0 -10
  153. package/dist/src/test/overlay-submit.test.js +0 -460
  154. package/dist/src/test/request-response-flow.test.d.ts +0 -5
  155. package/dist/src/test/request-response-flow.test.js +0 -210
  156. package/dist/src/test/service-system.test.d.ts +0 -5
  157. package/dist/src/test/service-system.test.js +0 -190
  158. package/dist/src/test/taskflow.test.d.ts +0 -7
  159. package/dist/src/test/taskflow.test.js +0 -82
  160. package/dist/src/test/utils/server-logic.d.ts +0 -98
  161. package/dist/src/test/utils/server-logic.js +0 -286
  162. package/dist/src/test/wallet.test.d.ts +0 -7
  163. package/dist/src/test/wallet.test.js +0 -146
  164. package/src/core/README.md +0 -246
  165. package/src/core/config.d.ts +0 -12
  166. package/src/core/config.d.ts.map +0 -1
  167. package/src/core/config.js +0 -14
  168. package/src/core/config.js.map +0 -1
  169. package/src/core/config.ts +0 -22
  170. package/src/core/index.ts +0 -42
  171. package/src/core/payment.d.ts +0 -17
  172. package/src/core/payment.d.ts.map +0 -1
  173. package/src/core/payment.js +0 -95
  174. package/src/core/payment.js.map +0 -1
  175. package/src/core/payment.ts +0 -111
  176. package/src/core/types.d.ts +0 -95
  177. package/src/core/types.d.ts.map +0 -1
  178. package/src/core/types.js +0 -5
  179. package/src/core/types.js.map +0 -1
  180. package/src/core/types.ts +0 -102
  181. package/src/core/verify.d.ts +0 -29
  182. package/src/core/verify.d.ts.map +0 -1
  183. package/src/core/verify.js +0 -105
  184. package/src/core/verify.js.map +0 -1
  185. package/src/core/verify.ts +0 -119
  186. package/src/core/wallet.d.ts +0 -100
  187. package/src/core/wallet.d.ts.map +0 -1
  188. package/src/core/wallet.js.map +0 -1
  189. package/src/core/wallet.ts +0 -323
@@ -1,75 +0,0 @@
1
- /**
2
- * Configuration constants and environment variables for the overlay CLI.
3
- */
4
- import path from 'node:path';
5
- import os from 'node:os';
6
- import fs from 'node:fs';
7
- // Auto-load .env from overlay state dir if it exists
8
- const overlayEnvPath = path.join(os.homedir(), '.openclaw', 'openclaw-overlay', '.env');
9
- try {
10
- if (fs.existsSync(overlayEnvPath)) {
11
- for (const line of fs.readFileSync(overlayEnvPath, 'utf-8').split('\n')) {
12
- const match = line.match(/^([A-Z_]+)=(.+)$/);
13
- if (match && !process['en' + 'v'][match[1]]) {
14
- process['en' + 'v'][match[1]] = match[2]?.trim();
15
- }
16
- }
17
- }
18
- }
19
- catch {
20
- // Ignore errors loading .env
21
- }
22
- /** Wallet storage directory */
23
- export const WALLET_DIR = process['en' + 'v'].BSV_WALLET_DIR
24
- || path.join(os.homedir(), '.openclaw', 'bsv-wallet');
25
- /** Network to use (mainnet or testnet) */
26
- export const NETWORK = process['en' + 'v'].BSV_NETWORK || 'mainnet';
27
- /** Overlay server URL */
28
- export const OVERLAY_URL = process['en' + 'v'].OVERLAY_URL || 'https://clawoverlay.com';
29
- /** Agent display name on the overlay network */
30
- export const AGENT_NAME = process['en' + 'v'].AGENT_NAME || 'openclaw-agent';
31
- /** Agent description for the overlay identity */
32
- export const AGENT_DESCRIPTION = process['en' + 'v'].AGENT_DESCRIPTION ||
33
- `AI agent on the OpenClaw Overlay Network. Offers services for BSV micropayments.`;
34
- /** WhatsOnChain API key (optional, for rate limit bypass) */
35
- export const WOC_API_KEY = process['en' + 'v'].WOC_API_KEY || '';
36
- /** Overlay state directory for registration, services, etc. */
37
- export const OVERLAY_STATE_DIR = path.join(os.homedir(), '.openclaw', 'openclaw-overlay');
38
- /** Protocol identifier for overlay transactions */
39
- export const PROTOCOL_ID = 'clawdbot-overlay-v1';
40
- /** Topic managers for overlay submissions */
41
- export const TOPICS = {
42
- IDENTITY: 'tm_clawdbot_identity',
43
- SERVICES: 'tm_clawdbot_services',
44
- X_VERIFICATION: 'tm_clawdbot_x_verification',
45
- SHIP: 'tm_ship',
46
- SLAP: 'tm_slap',
47
- };
48
- /** Default SLAP trackers */
49
- export const DEFAULT_SLAP_TRACKERS = {
50
- mainnet: ['https://overlay.babbage.systems'],
51
- testnet: ['https://testnet-users.bapp.dev'],
52
- };
53
- /** Lookup services for overlay queries */
54
- export const LOOKUP_SERVICES = {
55
- AGENTS: 'ls_clawdbot_agents',
56
- SERVICES: 'ls_clawdbot_services',
57
- X_VERIFICATIONS: 'ls_clawdbot_x_verifications',
58
- };
59
- /** Paths derived from config */
60
- export const PATHS = {
61
- walletIdentity: path.join(WALLET_DIR, 'wallet-identity.json'),
62
- registration: path.join(OVERLAY_STATE_DIR, 'registration.json'),
63
- services: path.join(OVERLAY_STATE_DIR, 'services.json'),
64
- latestChange: path.join(OVERLAY_STATE_DIR, 'latest-change.json'),
65
- receivedPayments: path.join(OVERLAY_STATE_DIR, 'received-payments.jsonl'),
66
- researchQueue: path.join(OVERLAY_STATE_DIR, 'research-queue.jsonl'),
67
- serviceQueue: path.join(OVERLAY_STATE_DIR, 'service-queue.jsonl'),
68
- notifications: path.join(OVERLAY_STATE_DIR, 'notifications.jsonl'),
69
- xVerifications: path.join(OVERLAY_STATE_DIR, 'x-verifications.json'),
70
- pendingXVerification: path.join(OVERLAY_STATE_DIR, 'pending-x-verification.json'),
71
- xEngagementQueue: path.join(OVERLAY_STATE_DIR, 'x-engagement-queue.jsonl'),
72
- memoryStore: path.join(WALLET_DIR, 'memory-store.json'),
73
- baemailConfig: path.join(OVERLAY_STATE_DIR, 'baemail-config.json'),
74
- baemailLog: path.join(OVERLAY_STATE_DIR, 'baemail-log.jsonl'),
75
- };
@@ -1,7 +0,0 @@
1
- /**
2
- * Main exports for lib modules.
3
- */
4
- export * from './types.js';
5
- export * from './config.js';
6
- export * from './output.js';
7
- export * from './baemail/index.js';
@@ -1,7 +0,0 @@
1
- /**
2
- * Main exports for lib modules.
3
- */
4
- export * from './types.js';
5
- export * from './config.js';
6
- export * from './output.js';
7
- export * from './baemail/index.js';
@@ -1,8 +0,0 @@
1
- /**
2
- * Connect command: WebSocket real-time message processing.
3
- */
4
- /**
5
- * Connect command: establish WebSocket connection for real-time messaging.
6
- * Supports being used as a library with onMessage callback and AbortSignal.
7
- */
8
- export declare function cmdConnect(onMessage?: (data: any) => void, signal?: AbortSignal): Promise<void>;
@@ -1,168 +0,0 @@
1
- /**
2
- * Connect command: WebSocket real-time message processing.
3
- */
4
- import fs from 'node:fs';
5
- import { OVERLAY_URL, PATHS } from '../config.js';
6
- import { fail } from '../output.js';
7
- import { loadIdentity } from '../wallet/identity.js';
8
- import { processMessage } from './handlers.js';
9
- import { ensureStateDir } from '../utils/storage.js';
10
- import debug from 'debug';
11
- const log = debug('openclaw:plugin:overlay:connect');
12
- /**
13
- * Connect command: establish WebSocket connection for real-time messaging.
14
- * Supports being used as a library with onMessage callback and AbortSignal.
15
- */
16
- export async function cmdConnect(onMessage, signal) {
17
- let WebSocketClient;
18
- try {
19
- const ws = await import('ws');
20
- WebSocketClient = ws.default || ws.WebSocket || ws;
21
- }
22
- catch {
23
- return fail('WebSocket client not available. Install it: npm install ws');
24
- }
25
- const { identityKey, privKey } = await loadIdentity();
26
- const wsUrl = OVERLAY_URL.replace(/^http/, 'ws') + '/relay/subscribe?identity=' + identityKey;
27
- log('Connecting to WebSocket relay: %s', wsUrl);
28
- let reconnectDelay = 1000;
29
- let shouldReconnect = true;
30
- let currentWs = null;
31
- function shutdown() {
32
- shouldReconnect = false;
33
- if (currentWs) {
34
- try {
35
- currentWs.close();
36
- }
37
- catch { }
38
- }
39
- // Only exit if we're not running as a library
40
- if (!onMessage) {
41
- process.exit(0);
42
- }
43
- }
44
- if (!onMessage) {
45
- process.on('SIGINT', shutdown);
46
- process.on('SIGTERM', shutdown);
47
- }
48
- if (signal) {
49
- signal.addEventListener('abort', () => {
50
- shouldReconnect = false;
51
- if (currentWs) {
52
- try {
53
- currentWs.close();
54
- }
55
- catch { }
56
- }
57
- });
58
- }
59
- function connect() {
60
- if (signal?.aborted)
61
- return;
62
- const ws = new WebSocketClient(wsUrl);
63
- currentWs = ws;
64
- ws.on('open', () => {
65
- log('WebSocket connection established!');
66
- reconnectDelay = 1000; // reset on successful connect
67
- const logMsg = { event: 'connected', identity: identityKey, overlay: OVERLAY_URL };
68
- if (onMessage)
69
- onMessage(logMsg);
70
- else
71
- console.error(JSON.stringify(logMsg));
72
- });
73
- ws.on('message', async (data) => {
74
- log('Incoming WebSocket message received');
75
- try {
76
- const envelope = JSON.parse(data.toString());
77
- log('Message type: %s', envelope.type);
78
- if (envelope.type === 'message') {
79
- const result = await processMessage(envelope.message, identityKey, privKey);
80
- log('Processed message: %s', result.id);
81
- if (onMessage)
82
- onMessage(result);
83
- else
84
- console.log(JSON.stringify(result));
85
- // Also append to notification log
86
- ensureStateDir();
87
- try {
88
- fs.appendFileSync(PATHS.notifications, JSON.stringify({ ...result, _ts: Date.now() }) + '\n');
89
- }
90
- catch { }
91
- // Ack the message
92
- if (result.ack) {
93
- try {
94
- await fetch(OVERLAY_URL + '/relay/ack', {
95
- method: 'POST',
96
- headers: { 'Content-Type': 'application/json' },
97
- body: JSON.stringify({ identity: identityKey, messageIds: [result.id] }),
98
- });
99
- }
100
- catch (ackErr) {
101
- const log = { event: 'ack-error', id: result.id, message: String(ackErr) };
102
- if (onMessage)
103
- onMessage(log);
104
- else
105
- console.error(JSON.stringify(log));
106
- }
107
- }
108
- }
109
- // Handle service announcements
110
- if (envelope.type === 'service-announced') {
111
- const svc = envelope.service || {};
112
- const announcement = {
113
- event: 'service-announced',
114
- serviceId: svc.serviceId,
115
- name: svc.name,
116
- description: svc.description,
117
- priceSats: svc.pricingSats,
118
- provider: svc.identityKey,
119
- txid: envelope.txid,
120
- _ts: Date.now(),
121
- };
122
- if (onMessage)
123
- onMessage(announcement);
124
- else
125
- console.log(JSON.stringify(announcement));
126
- ensureStateDir();
127
- try {
128
- fs.appendFileSync(PATHS.notifications, JSON.stringify(announcement) + '\n');
129
- }
130
- catch { }
131
- }
132
- }
133
- catch (err) {
134
- const log = { event: 'process-error', message: String(err) };
135
- if (onMessage)
136
- onMessage(log);
137
- else
138
- console.error(JSON.stringify(log));
139
- }
140
- });
141
- ws.on('close', () => {
142
- currentWs = null;
143
- if (shouldReconnect && !signal?.aborted) {
144
- const log = { event: 'disconnected', reconnectMs: reconnectDelay };
145
- if (onMessage)
146
- onMessage(log);
147
- else
148
- console.error(JSON.stringify(log));
149
- setTimeout(connect, reconnectDelay);
150
- reconnectDelay = Math.min(reconnectDelay * 2, 30000);
151
- }
152
- });
153
- ws.on('error', (err) => {
154
- const log = { event: 'error', message: err.message };
155
- if (onMessage)
156
- onMessage(log);
157
- else
158
- console.error(JSON.stringify(log));
159
- });
160
- }
161
- connect();
162
- // Keep alive
163
- return new Promise((resolve) => {
164
- if (signal) {
165
- signal.addEventListener('abort', () => resolve());
166
- }
167
- });
168
- }
@@ -1,21 +0,0 @@
1
- /**
2
- * Message type handlers and processMessage function.
3
- */
4
- import type { RelayMessage, ProcessMessageResult } from '../types.js';
5
- /**
6
- * Verify and accept a payment from a service request.
7
- * Uses a2a-bsv wallet.acceptPayment() for proper BRC-29 handling.
8
- */
9
- export declare function verifyAndAcceptPayment(payment: any, minSats: number, senderKey: string, serviceId: string, ourHash160: Uint8Array): Promise<{
10
- accepted: boolean;
11
- txid: string | null;
12
- satoshis: number;
13
- outputIndex: number;
14
- walletAccepted: boolean;
15
- error: string | null;
16
- }>;
17
- /**
18
- * Process a single relay message.
19
- * Handles pings, service requests, pongs, and service responses.
20
- */
21
- export declare function processMessage(msg: RelayMessage, identityKey: string, privKey: any): Promise<ProcessMessageResult>;
@@ -1,334 +0,0 @@
1
- /**
2
- * Message type handlers and processMessage function.
3
- */
4
- import fs from 'node:fs';
5
- import { OVERLAY_URL, WALLET_DIR, PATHS } from '../config.js';
6
- import { signRelayMessage, verifyRelaySignature, loadWalletIdentity } from '../wallet/identity.js';
7
- import { loadServices, appendToJsonl } from '../utils/storage.js';
8
- import { fetchWithTimeout } from '../utils/woc.js';
9
- import { serviceManager } from '../../services/index.js';
10
- // Dynamic import for @bsv/sdk (needed for hash160 computation)
11
- let _sdk = null;
12
- async function getSdk() {
13
- if (_sdk)
14
- return _sdk;
15
- try {
16
- _sdk = await import('@bsv/sdk');
17
- return _sdk;
18
- }
19
- catch {
20
- const { fileURLToPath } = await import('node:url');
21
- const path = await import('node:path');
22
- const os = await import('node:os');
23
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
24
- const candidates = [
25
- path.resolve(__dirname, '..', '..', '..', 'node_modules', '@bsv', 'sdk', 'dist', 'esm', 'mod.js'),
26
- path.resolve(__dirname, '..', '..', '..', '..', '..', 'a2a-bsv', 'packages', 'core', 'node_modules', '@bsv', 'sdk', 'dist', 'esm', 'mod.js'),
27
- path.resolve(os.homedir(), 'a2a-bsv', 'packages', 'core', 'node_modules', '@bsv', 'sdk', 'dist', 'esm', 'mod.js'),
28
- ];
29
- for (const p of candidates) {
30
- try {
31
- _sdk = await import(p);
32
- return _sdk;
33
- }
34
- catch {
35
- // Try next
36
- }
37
- }
38
- throw new Error('Cannot find @bsv/sdk. Run setup.sh first.');
39
- }
40
- }
41
- import { BSVAgentWallet } from '../../core/index.js';
42
- async function getBSVAgentWallet() {
43
- return BSVAgentWallet;
44
- }
45
- // Import NETWORK lazily to avoid circular dependencies
46
- async function getNetwork() {
47
- const config = await import('../config.js');
48
- return config.NETWORK;
49
- }
50
- /**
51
- * Verify and accept a payment from a service request.
52
- * Uses a2a-bsv wallet.acceptPayment() for proper BRC-29 handling.
53
- */
54
- export async function verifyAndAcceptPayment(payment, minSats, senderKey, serviceId, ourHash160) {
55
- if (!payment) {
56
- return { accepted: false, txid: null, satoshis: 0, outputIndex: 0, walletAccepted: false, error: 'no payment' };
57
- }
58
- if (payment.error) {
59
- return { accepted: false, txid: null, satoshis: 0, outputIndex: 0, walletAccepted: false, error: payment.error };
60
- }
61
- if (!payment.beef || !payment.satoshis) {
62
- return { accepted: false, txid: null, satoshis: 0, outputIndex: 0, walletAccepted: false, error: 'missing beef or satoshis' };
63
- }
64
- if (payment.satoshis < minSats) {
65
- return { accepted: false, txid: payment.txid || null, satoshis: payment.satoshis, outputIndex: 0, walletAccepted: false, error: `insufficient payment: ${payment.satoshis} < ${minSats}` };
66
- }
67
- // Accept the payment using a2a-bsv wallet
68
- const BSVAgentWallet = await getBSVAgentWallet();
69
- const network = await getNetwork();
70
- const wallet = await BSVAgentWallet.load({ network, storageDir: WALLET_DIR });
71
- try {
72
- // First verify the payment structure
73
- const verifyResult = await wallet.verifyPayment({ beef: payment.beef });
74
- if (!verifyResult.valid) {
75
- await wallet.destroy();
76
- return { accepted: false, txid: payment.txid || null, satoshis: payment.satoshis, outputIndex: 0, walletAccepted: false, error: `verification failed: ${verifyResult.errors.join(', ')}` };
77
- }
78
- // Accept the payment (this broadcasts the transaction)
79
- const acceptResult = await wallet.acceptPayment({
80
- beef: payment.beef,
81
- derivationPrefix: payment.derivationPrefix,
82
- derivationSuffix: payment.derivationSuffix,
83
- senderIdentityKey: payment.senderIdentityKey,
84
- description: `Payment for ${serviceId}`,
85
- });
86
- await wallet.destroy();
87
- if (!acceptResult.accepted) {
88
- return { accepted: false, txid: payment.txid || null, satoshis: payment.satoshis, outputIndex: 0, walletAccepted: false, error: 'wallet rejected payment' };
89
- }
90
- return {
91
- accepted: true,
92
- txid: payment.txid,
93
- satoshis: payment.satoshis,
94
- outputIndex: 0,
95
- walletAccepted: true,
96
- error: null,
97
- };
98
- }
99
- catch (err) {
100
- await wallet.destroy();
101
- return { accepted: false, txid: payment.txid || null, satoshis: payment.satoshis, outputIndex: 0, walletAccepted: false, error: err.message };
102
- }
103
- }
104
- /**
105
- * Queue a service request for agent processing.
106
- */
107
- async function queueForAgent(msg, identityKey, privKey, serviceId) {
108
- // Check if this request has already been processed to prevent duplicates
109
- if (fs.existsSync(PATHS.serviceQueue)) {
110
- const lines = fs.readFileSync(PATHS.serviceQueue, 'utf-8').trim().split('\n').filter(Boolean);
111
- for (const line of lines) {
112
- try {
113
- const entry = JSON.parse(line);
114
- if (entry.requestId === msg.id) {
115
- // Request already exists in queue - return existing status
116
- return {
117
- id: msg.id,
118
- type: 'service-request',
119
- serviceId,
120
- action: entry.status === 'pending' ? 'already-queued' : `already-${entry.status}`,
121
- paymentAccepted: true,
122
- paymentTxid: entry.paymentTxid,
123
- satoshisReceived: entry.satoshisReceived,
124
- from: msg.from,
125
- ack: true,
126
- };
127
- }
128
- }
129
- catch { }
130
- }
131
- }
132
- const sdk = await getSdk();
133
- const payment = msg.payload?.payment;
134
- const input = msg.payload?.input || msg.payload;
135
- // Verify and accept payment
136
- const walletIdentity = loadWalletIdentity();
137
- const ourHash160 = sdk.Hash.hash160(sdk.PrivateKey.fromHex(walletIdentity.rootKeyHex).toPublicKey().encode(true));
138
- // Find the service price using the service registry
139
- const serviceDefinition = serviceManager.registry.get(serviceId);
140
- let minPrice = 5; // default fallback
141
- if (serviceDefinition) {
142
- minPrice = serviceDefinition.defaultPrice;
143
- // Validate service input if possible
144
- const validation = serviceManager.validate(serviceId, input);
145
- if (!validation.valid) {
146
- // Send validation rejection
147
- const rejectPayload = {
148
- requestId: msg.id,
149
- serviceId,
150
- status: 'rejected',
151
- reason: `Input validation failed: ${validation.error}`
152
- };
153
- const sig = await signRelayMessage(privKey, msg.from, 'service-response', rejectPayload);
154
- await fetchWithTimeout(`${OVERLAY_URL}/relay/send`, {
155
- method: 'POST',
156
- headers: { 'Content-Type': 'application/json' },
157
- body: JSON.stringify({ from: identityKey, to: msg.from, type: 'service-response', payload: rejectPayload, signature: sig }),
158
- });
159
- // Also add the rejected entry to the queue for tracking
160
- const rejectedEntry = {
161
- status: 'rejected',
162
- requestId: msg.id,
163
- serviceId,
164
- from: msg.from,
165
- identityKey,
166
- input: input,
167
- paymentTxid: null,
168
- satoshisReceived: 0,
169
- walletAccepted: false,
170
- error: validation.error,
171
- _ts: Date.now(),
172
- };
173
- appendToJsonl(PATHS.serviceQueue, rejectedEntry);
174
- return {
175
- id: msg.id,
176
- type: 'service-request',
177
- serviceId,
178
- action: 'rejected',
179
- reason: validation.error || 'input validation failed',
180
- from: msg.from,
181
- ack: true
182
- };
183
- }
184
- }
185
- else {
186
- // Fall back to legacy service loading for backward compatibility
187
- const services = loadServices();
188
- const svc = services.find(s => s.serviceId === serviceId);
189
- minPrice = svc?.priceSats || 5;
190
- }
191
- const payResult = await verifyAndAcceptPayment(payment, minPrice, msg.from, serviceId, ourHash160);
192
- if (!payResult.accepted) {
193
- // Send rejection
194
- const rejectPayload = { requestId: msg.id, serviceId, status: 'rejected', reason: `Payment rejected: ${payResult.error}` };
195
- const sig = await signRelayMessage(privKey, msg.from, 'service-response', rejectPayload);
196
- await fetchWithTimeout(`${OVERLAY_URL}/relay/send`, {
197
- method: 'POST',
198
- headers: { 'Content-Type': 'application/json' },
199
- body: JSON.stringify({ from: identityKey, to: msg.from, type: 'service-response', payload: rejectPayload, signature: sig }),
200
- });
201
- // Also add the rejected entry to the queue for tracking
202
- const rejectedEntry = {
203
- status: 'rejected',
204
- requestId: msg.id,
205
- serviceId,
206
- from: msg.from,
207
- identityKey,
208
- input: input,
209
- paymentTxid: null,
210
- satoshisReceived: 0,
211
- walletAccepted: false,
212
- error: payResult.error,
213
- _ts: Date.now(),
214
- };
215
- appendToJsonl(PATHS.serviceQueue, rejectedEntry);
216
- return { id: msg.id, type: 'service-request', serviceId, action: 'rejected', reason: payResult.error || 'payment rejected', from: msg.from, ack: true };
217
- }
218
- // Queue for agent processing
219
- const queueEntry = {
220
- status: 'pending',
221
- requestId: msg.id,
222
- serviceId,
223
- from: msg.from,
224
- identityKey,
225
- input: input,
226
- paymentTxid: payResult.txid,
227
- satoshisReceived: payResult.satoshis,
228
- walletAccepted: payResult.walletAccepted,
229
- _ts: Date.now(),
230
- };
231
- appendToJsonl(PATHS.serviceQueue, queueEntry);
232
- return {
233
- id: msg.id,
234
- type: 'service-request',
235
- serviceId,
236
- action: 'queued-for-agent',
237
- paymentAccepted: true,
238
- paymentTxid: payResult.txid,
239
- satoshisReceived: payResult.satoshis,
240
- from: msg.from,
241
- ack: true,
242
- };
243
- }
244
- /**
245
- * Process a single relay message.
246
- * Handles pings, service requests, pongs, and service responses.
247
- */
248
- export async function processMessage(msg, identityKey, privKey) {
249
- // Verify signature if present
250
- const sigCheck = msg.signature
251
- ? await verifyRelaySignature(msg.from, msg.to, msg.type, msg.payload, msg.signature)
252
- : { valid: null };
253
- // Reject unsigned/forged service-requests
254
- if (msg.type === 'service-request' && sigCheck.valid !== true) {
255
- console.error(JSON.stringify({ event: 'signature-rejected', type: msg.type, from: msg.from, reason: sigCheck.reason || 'missing signature' }));
256
- return {
257
- id: msg.id,
258
- type: msg.type,
259
- from: msg.from,
260
- action: 'rejected',
261
- reason: 'invalid-signature',
262
- signatureValid: sigCheck.valid,
263
- ack: true,
264
- };
265
- }
266
- if (msg.type === 'ping') {
267
- // Auto-respond with pong
268
- const pongPayload = {
269
- text: 'pong',
270
- inReplyTo: msg.id,
271
- originalText: msg.payload?.text || null,
272
- };
273
- const pongSig = await signRelayMessage(privKey, msg.from, 'pong', pongPayload);
274
- await fetch(`${OVERLAY_URL}/relay/send`, {
275
- method: 'POST',
276
- headers: { 'Content-Type': 'application/json' },
277
- body: JSON.stringify({
278
- from: identityKey,
279
- to: msg.from,
280
- type: 'pong',
281
- payload: pongPayload,
282
- signature: pongSig,
283
- }),
284
- });
285
- return { id: msg.id, type: 'ping', action: 'replied-pong', from: msg.from, ack: true };
286
- }
287
- if (msg.type === 'service-request') {
288
- const serviceId = msg.payload?.serviceId;
289
- // Agent-routed mode: queue for the agent
290
- if (process['en' + 'v'].AGENT_ROUTED === 'true') {
291
- return await queueForAgent(msg, identityKey, privKey, serviceId);
292
- }
293
- // No hardcoded handlers in TypeScript version — always queue
294
- return await queueForAgent(msg, identityKey, privKey, serviceId);
295
- }
296
- if (msg.type === 'pong') {
297
- return {
298
- id: msg.id,
299
- type: 'pong',
300
- action: 'received',
301
- from: msg.from,
302
- text: msg.payload?.text,
303
- inReplyTo: msg.payload?.inReplyTo,
304
- ack: true,
305
- };
306
- }
307
- if (msg.type === 'service-response') {
308
- const serviceId = msg.payload?.serviceId;
309
- const status = msg.payload?.status;
310
- const result = msg.payload?.result;
311
- return {
312
- id: msg.id,
313
- type: 'service-response',
314
- action: 'received',
315
- from: msg.from,
316
- serviceId,
317
- status,
318
- result,
319
- requestId: msg.payload?.requestId,
320
- direction: 'incoming-response',
321
- ack: true,
322
- };
323
- }
324
- // Unknown type
325
- return {
326
- id: msg.id,
327
- type: msg.type,
328
- from: msg.from,
329
- payload: msg.payload,
330
- signatureValid: sigCheck.valid,
331
- action: 'unhandled',
332
- ack: false,
333
- };
334
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * Inbox and ack commands.
3
- */
4
- /**
5
- * Inbox command: fetch pending messages.
6
- */
7
- export declare function cmdInbox(args: string[]): Promise<any>;
8
- /**
9
- * Ack command: acknowledge processed messages.
10
- */
11
- export declare function cmdAck(messageIds: string[]): Promise<any>;