openclaw-overlay-plugin 0.8.18 → 0.8.20

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 (84) hide show
  1. package/dist/index.js +607 -853
  2. package/dist/index.js.map +4 -4
  3. package/dist/src/cli.js +30 -568
  4. package/dist/src/cli.js.map +4 -4
  5. package/package.json +5 -5
  6. package/index.ts +0 -379
  7. package/src/ambient.d.ts +0 -1
  8. package/src/cli-main.ts +0 -240
  9. package/src/cli.ts +0 -16
  10. package/src/compatibility.test.ts +0 -46
  11. package/src/scripts/baemail/commands.ts +0 -311
  12. package/src/scripts/baemail/handler.ts +0 -338
  13. package/src/scripts/baemail/index.ts +0 -6
  14. package/src/scripts/config.ts +0 -89
  15. package/src/scripts/index.ts +0 -8
  16. package/src/scripts/messaging/connect.ts +0 -162
  17. package/src/scripts/messaging/handlers.ts +0 -394
  18. package/src/scripts/messaging/inbox.ts +0 -64
  19. package/src/scripts/messaging/index.ts +0 -9
  20. package/src/scripts/messaging/poll.ts +0 -59
  21. package/src/scripts/messaging/send.ts +0 -54
  22. package/src/scripts/output.ts +0 -30
  23. package/src/scripts/overlay/advertisement.ts +0 -138
  24. package/src/scripts/overlay/discover.ts +0 -83
  25. package/src/scripts/overlay/index.ts +0 -8
  26. package/src/scripts/overlay/registration.ts +0 -199
  27. package/src/scripts/overlay/services.ts +0 -199
  28. package/src/scripts/overlay/transaction.ts +0 -124
  29. package/src/scripts/payment/build.ts +0 -65
  30. package/src/scripts/payment/commands.ts +0 -92
  31. package/src/scripts/payment/index.ts +0 -7
  32. package/src/scripts/payment/types.ts +0 -62
  33. package/src/scripts/services/index.ts +0 -7
  34. package/src/scripts/services/queue.ts +0 -35
  35. package/src/scripts/services/request.ts +0 -98
  36. package/src/scripts/services/respond.ts +0 -149
  37. package/src/scripts/types.ts +0 -121
  38. package/src/scripts/utils/index.ts +0 -7
  39. package/src/scripts/utils/merkle.ts +0 -57
  40. package/src/scripts/utils/storage.ts +0 -231
  41. package/src/scripts/utils/woc.ts +0 -106
  42. package/src/scripts/wallet/balance.ts +0 -277
  43. package/src/scripts/wallet/identity.ts +0 -204
  44. package/src/scripts/wallet/index.ts +0 -7
  45. package/src/scripts/wallet/setup.ts +0 -137
  46. package/src/scripts/x-verification/commands.ts +0 -261
  47. package/src/scripts/x-verification/index.ts +0 -5
  48. package/src/services/built-in/api-proxy/index.ts +0 -26
  49. package/src/services/built-in/api-proxy/prompt.md +0 -26
  50. package/src/services/built-in/code-develop/index.ts +0 -26
  51. package/src/services/built-in/code-develop/prompt.md +0 -35
  52. package/src/services/built-in/code-review/index.ts +0 -54
  53. package/src/services/built-in/code-review/prompt.md +0 -105
  54. package/src/services/built-in/image-analysis/index.ts +0 -36
  55. package/src/services/built-in/image-analysis/prompt.md +0 -42
  56. package/src/services/built-in/memory-store/index.ts +0 -25
  57. package/src/services/built-in/memory-store/prompt.md +0 -45
  58. package/src/services/built-in/roulette/index.ts +0 -30
  59. package/src/services/built-in/roulette/prompt.md +0 -35
  60. package/src/services/built-in/summarize/index.ts +0 -24
  61. package/src/services/built-in/summarize/prompt.md +0 -27
  62. package/src/services/built-in/tell-joke/handler.ts +0 -134
  63. package/src/services/built-in/tell-joke/index.ts +0 -34
  64. package/src/services/built-in/tell-joke/prompt.md +0 -59
  65. package/src/services/built-in/translate/index.ts +0 -24
  66. package/src/services/built-in/translate/prompt.md +0 -23
  67. package/src/services/built-in/web-research/index.ts +0 -54
  68. package/src/services/built-in/web-research/prompt.md +0 -110
  69. package/src/services/index.ts +0 -16
  70. package/src/services/loader.ts +0 -344
  71. package/src/services/manager.ts +0 -304
  72. package/src/services/registry.ts +0 -246
  73. package/src/services/types.ts +0 -259
  74. package/src/test/cli.test.ts +0 -353
  75. package/src/test/comprehensive-overlay.test.ts +0 -729
  76. package/src/test/identity-consistency.test.ts +0 -68
  77. package/src/test/key-derivation.test.ts +0 -102
  78. package/src/test/network-address.test.ts +0 -46
  79. package/src/test/overlay-submit.test.ts +0 -570
  80. package/src/test/request-response-flow.test.ts +0 -253
  81. package/src/test/service-system.test.ts +0 -241
  82. package/src/test/taskflow.test.ts +0 -95
  83. package/src/test/utils/server-logic.ts +0 -368
  84. package/src/test/wallet.test.ts +0 -165
@@ -1,199 +0,0 @@
1
- /**
2
- * Overlay service commands: services, advertise, remove, readvertise.
3
- *
4
- * Service payloads match the openclaw-overlay server schema:
5
- * - protocol: "clawdbot-overlay-v1"
6
- * - type: "service"
7
- * - identityKey: provider's compressed public key
8
- * - serviceId: unique service identifier
9
- * - name: human-readable name
10
- * - description: what the service does
11
- * - pricing: { model: "per-task", amountSats: number }
12
- * - timestamp: ISO 8601 time
13
- */
14
-
15
- import { NETWORK, WALLET_DIR, PROTOCOL_ID, TOPICS } from '../config.js';
16
- import { ok, fail } from '../output.js';
17
- import { loadServices, saveServices } from '../utils/storage.js';
18
- import { buildRealOverlayTransaction } from './transaction.js';
19
- import type { ServiceAdvertisement } from '../types.js';
20
-
21
- import { BSVAgentWallet } from 'openclaw-plugin-core';
22
-
23
- async function getBSVAgentWallet(): Promise<typeof BSVAgentWallet> {
24
- return BSVAgentWallet;
25
- }
26
-
27
- /**
28
- * Services command: list currently advertised services.
29
- */
30
- export async function cmdServices(): Promise<any> {
31
- const services = loadServices();
32
- return ok({ services, count: services.length });
33
- }
34
-
35
- /**
36
- * Advertise command: add a new service advertisement.
37
- */
38
- export async function cmdAdvertise(
39
- serviceId: string | undefined,
40
- name: string | undefined,
41
- priceSatsStr: string | undefined,
42
- description?: string
43
- ): Promise<any> {
44
- if (!serviceId || !name || !priceSatsStr) {
45
- return fail('Usage: advertise <serviceId> <name> <priceSats> [description]');
46
- }
47
-
48
- const priceSats = parseInt(priceSatsStr, 10);
49
- if (isNaN(priceSats) || priceSats < 0) {
50
- return fail('priceSats must be a non-negative integer');
51
- }
52
-
53
- const BSVAgentWallet = await getBSVAgentWallet();
54
- const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
55
- const identityKey = await wallet.getIdentityKey();
56
- await wallet.destroy();
57
-
58
- // Load existing services
59
- const services = loadServices();
60
- const existing = services.find(s => s.serviceId === serviceId);
61
- if (existing) {
62
- return fail(`Service '${serviceId}' already exists. Use 'readvertise' to update.`);
63
- }
64
-
65
- // Create service record (local storage format)
66
- const newService: ServiceAdvertisement = {
67
- serviceId,
68
- name,
69
- description: description || `${name} service`,
70
- priceSats,
71
- registeredAt: new Date().toISOString(),
72
- };
73
-
74
- // Publish on-chain (matches openclaw-overlay server schema)
75
- const servicePayload = {
76
- protocol: PROTOCOL_ID,
77
- type: 'service' as const,
78
- identityKey,
79
- serviceId,
80
- name,
81
- description: newService.description,
82
- pricing: {
83
- model: 'per-task',
84
- amountSats: priceSats,
85
- },
86
- timestamp: new Date().toISOString(),
87
- };
88
-
89
- try {
90
- const result = await buildRealOverlayTransaction(servicePayload, TOPICS.SERVICES);
91
- newService.txid = result.txid;
92
-
93
- // Save locally
94
- services.push(newService);
95
- saveServices(services);
96
-
97
- return ok({
98
- advertised: true,
99
- service: newService,
100
- txid: result.txid,
101
- funded: result.funded,
102
- });
103
- } catch (err: any) {
104
- return fail(`Failed to advertise service: ${err.message}`);
105
- }
106
- }
107
-
108
- /**
109
- * Remove command: remove a service from local registry.
110
- */
111
- export async function cmdRemove(serviceId: string | undefined): Promise<any> {
112
- if (!serviceId) {
113
- return fail('Usage: remove <serviceId>');
114
- }
115
-
116
- const services = loadServices();
117
- const idx = services.findIndex(s => s.serviceId === serviceId);
118
- if (idx === -1) {
119
- return fail(`Service '${serviceId}' not found`);
120
- }
121
-
122
- const removed = services.splice(idx, 1)[0];
123
- saveServices(services);
124
-
125
- return ok({
126
- removed: true,
127
- service: removed,
128
- note: 'Removed from local registry. On-chain record remains (blockchain is immutable).',
129
- });
130
- }
131
-
132
- /**
133
- * Readvertise command: update an existing service advertisement.
134
- */
135
- export async function cmdReadvertise(
136
- serviceId: string | undefined,
137
- name?: string,
138
- priceSatsStr?: string,
139
- description?: string
140
- ): Promise<any> {
141
- if (!serviceId) {
142
- return fail('Usage: readvertise <serviceId> [name] [priceSats] [description]');
143
- }
144
-
145
- const services = loadServices();
146
- const existing = services.find(s => s.serviceId === serviceId);
147
- if (!existing) {
148
- return fail(`Service '${serviceId}' not found. Use 'advertise' to create.`);
149
- }
150
-
151
- const BSVAgentWallet = await getBSVAgentWallet();
152
- const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
153
- const identityKey = await wallet.getIdentityKey();
154
- await wallet.destroy();
155
-
156
- // Update fields if provided
157
- if (name) existing.name = name;
158
- if (priceSatsStr) {
159
- const priceSats = parseInt(priceSatsStr, 10);
160
- if (isNaN(priceSats) || priceSats < 0) {
161
- return fail('priceSats must be a non-negative integer');
162
- }
163
- existing.priceSats = priceSats;
164
- }
165
- if (description) existing.description = description;
166
- existing.registeredAt = new Date().toISOString();
167
-
168
- // Publish update on-chain (matches openclaw-overlay server schema)
169
- const servicePayload = {
170
- protocol: PROTOCOL_ID,
171
- type: 'service' as const,
172
- identityKey,
173
- serviceId,
174
- name: existing.name,
175
- description: existing.description,
176
- pricing: {
177
- model: 'per-task',
178
- amountSats: existing.priceSats,
179
- },
180
- timestamp: existing.registeredAt,
181
- };
182
-
183
- try {
184
- const result = await buildRealOverlayTransaction(servicePayload, TOPICS.SERVICES);
185
- existing.txid = result.txid;
186
-
187
- // Save locally
188
- saveServices(services);
189
-
190
- return ok({
191
- readvertised: true,
192
- service: existing,
193
- txid: result.txid,
194
- funded: result.funded,
195
- });
196
- } catch (err: any) {
197
- return fail(`Failed to readvertise service: ${err.message}`);
198
- }
199
- }
@@ -1,124 +0,0 @@
1
- /**
2
- * Overlay transaction building utilities.
3
- *
4
- * Follows the openclaw-overlay server API:
5
- * - Submit: POST /submit with binary BEEF and X-Topics header
6
- * - OP_RETURN format: OP_FALSE OP_RETURN <"clawdbot-overlay-v1"> <JSON>
7
- */
8
-
9
- import { NETWORK, OVERLAY_URL, PROTOCOL_ID, WALLET_DIR } from '../config.js';
10
- import type { OverlayPayload } from '../types.js';
11
- import { Utils, PushDrop, Transaction } from '@bsv/sdk';
12
- import { BSVAgentWallet } from 'openclaw-plugin-core';
13
-
14
- /**
15
- * Build an PushDrop locking script with JSON payload using SDK's Script class.
16
- *
17
- * @param payload - The data to embed in the OP_RETURN
18
- * @returns A proper Script object that the SDK can serialize
19
- */
20
- export async function buildPushDropScript(wallet: BSVAgentWallet, payload: OverlayPayload): Promise<string> {
21
- const jsonBytes = Utils.toArray(JSON.stringify(payload), 'utf8')
22
- const fields: number[][] = [jsonBytes]
23
- const token = new PushDrop(wallet._setup.wallet);
24
- const script = await token.lock(fields, [0, PROTOCOL_ID], '1', 'self', true, true)
25
- return script.toHex();
26
- }
27
-
28
- /**
29
- * Build and submit an overlay transaction.
30
- * @param payload - JSON data to store in OP_RETURN
31
- * @param topic - Topic manager for submission
32
- * @returns Transaction result with txid and funding info
33
- */
34
- export async function buildRealOverlayTransaction(
35
- payload: OverlayPayload,
36
- topic: string
37
- ): Promise<{ txid: string; funded: string; explorer: string }> {
38
-
39
- const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR })
40
- const lockingScript = await buildPushDropScript(wallet, payload)
41
-
42
- const response = await wallet._setup.wallet.createAction({
43
- description: 'topic manager submission',
44
- outputs: [
45
- {
46
- lockingScript,
47
- satoshis: 1,
48
- outputDescription: 'overlay',
49
- basket: topic, // basket is the topic manager
50
- }
51
- ],
52
- options: {
53
- acceptDelayedBroadcast: false,
54
- }
55
- })
56
-
57
- // --- Submit to overlay ---
58
- // Use binary BEEF with X-Topics header (matches openclaw-overlay server API)
59
- const submitResp = await fetch(`${OVERLAY_URL}/submit`, {
60
- method: 'POST',
61
- headers: {
62
- 'Content-Type': 'application/octet-stream',
63
- 'X-Topics': JSON.stringify([topic]),
64
- },
65
- body: new Uint8Array(response.tx as number[]),
66
- });
67
-
68
- if (!submitResp.ok) {
69
- const errText = await submitResp.text();
70
- throw new Error(`Overlay submission failed: ${submitResp.status} — ${errText}`);
71
- }
72
-
73
- const wocNet = NETWORK === 'mainnet' ? '' : 'test.';
74
- return {
75
- txid: response.txid as string,
76
- funded: 'stored-beef',
77
- explorer: `https://${wocNet}whatsonchain.com/tx/${response.txid as string}`,
78
- };
79
- }
80
-
81
- /**
82
- * Lookup data from an overlay lookup service.
83
- */
84
- export async function lookupOverlay(
85
- service: string,
86
- query: Record<string, unknown>
87
- ): Promise<any> {
88
- const resp = await fetch(`${OVERLAY_URL}/lookup`, {
89
- method: 'POST',
90
- headers: { 'Content-Type': 'application/json' },
91
- body: JSON.stringify({ service, query }),
92
- });
93
-
94
- if (!resp.ok) {
95
- const errText = await resp.text();
96
- throw new Error(`Lookup failed: ${resp.status} — ${errText}`);
97
- }
98
-
99
- return resp.json();
100
- }
101
-
102
- /**
103
- * Parse an overlay output from BEEF data.
104
- *
105
- * Handles both formats:
106
- * - OP_FALSE OP_RETURN <protocol> <json> (standard)
107
- * - OP_RETURN <protocol> <json> (legacy)
108
- */
109
- export async function parseOverlayOutput(
110
- beefData: string | Uint8Array | number[],
111
- outputIndex: number
112
- ): Promise<{ data: OverlayPayload | null; txid: string | null }> {
113
- try {
114
- const tx = Transaction.fromBEEF(beefData as number[]);
115
- const txid = tx.id('hex')
116
- const output = tx.outputs[outputIndex];
117
- if (!output) return { data: null, txid: null };
118
-
119
- const { fields } = PushDrop.decode(output.lockingScript);
120
- return { data: JSON.parse(Utils.toUTF8(fields[0])), txid };
121
- } catch {
122
- return { data: null, txid: null };
123
- }
124
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * Payment building using a2a-bsv wallet.createPayment().
3
- *
4
- * This replaces the old buildDirectPayment() which used plain P2PKH scripts
5
- * and manual UTXO management. The new implementation:
6
- * - Uses proper BRC-29 locking scripts via wallet.createPayment()
7
- * - Relies on wallet's createAction() for UTXO management
8
- * - Uses noSend: true (recipient broadcasts via acceptPayment())
9
- */
10
-
11
- import { NETWORK, WALLET_DIR } from '../config.js';
12
- import type { PaymentResult } from './types.js';
13
-
14
- import { BSVAgentWallet } from 'openclaw-plugin-core';
15
-
16
- async function getBSVAgentWallet(): Promise<typeof BSVAgentWallet> {
17
- return BSVAgentWallet;
18
- }
19
-
20
- /**
21
- * Build a BRC-29 payment using the a2a-bsv wallet.
22
- *
23
- * This creates a payment transaction using proper BRC-29 locking scripts.
24
- * The transaction uses noSend: true, meaning:
25
- * - The sender does NOT broadcast the transaction
26
- * - The recipient broadcasts it when they call acceptPayment()
27
- *
28
- * @param recipientPubKey - Recipient's compressed public key (66 hex chars, 02/03 prefix)
29
- * @param sats - Amount to send in satoshis
30
- * @param desc - Optional description for the payment
31
- * @returns PaymentResult with BEEF and derivation metadata for the recipient
32
- */
33
- export async function buildDirectPayment(
34
- recipientPubKey: string,
35
- sats: number,
36
- desc?: string
37
- ): Promise<PaymentResult> {
38
- // Validate recipient pubkey format
39
- if (!/^0[23][0-9a-fA-F]{64}$/.test(recipientPubKey)) {
40
- throw new Error('Recipient must be a compressed public key (66 hex chars starting with 02 or 03)');
41
- }
42
-
43
- const BSVAgentWallet = await getBSVAgentWallet();
44
- const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
45
-
46
- try {
47
- const result = await wallet.createPayment({
48
- to: recipientPubKey,
49
- satoshis: sats,
50
- description: desc || 'agent payment',
51
- });
52
-
53
- // Return format compatible with existing code
54
- return {
55
- beef: result.beef,
56
- txid: result.txid,
57
- satoshis: result.satoshis,
58
- derivationPrefix: result.derivationPrefix,
59
- derivationSuffix: result.derivationSuffix,
60
- senderIdentityKey: result.senderIdentityKey,
61
- };
62
- } finally {
63
- await wallet.destroy();
64
- }
65
- }
@@ -1,92 +0,0 @@
1
- /**
2
- * Payment CLI commands: pay, verify, accept.
3
- */
4
-
5
- import { NETWORK, WALLET_DIR } from '../config.js';
6
- import { ok, fail } from '../output.js';
7
- import { buildDirectPayment } from './build.js';
8
-
9
- import { BSVAgentWallet } from 'openclaw-plugin-core';
10
-
11
- async function getBSVAgentWallet(): Promise<typeof BSVAgentWallet> {
12
- return BSVAgentWallet;
13
- }
14
-
15
- /**
16
- * Pay command: send satoshis to another agent.
17
- */
18
- export async function cmdPay(
19
- pubkey: string | undefined,
20
- satoshis: string | undefined,
21
- description?: string
22
- ): Promise<any> {
23
- if (!pubkey || !satoshis) {
24
- return fail('Usage: pay <pubkey> <satoshis> [description]');
25
- }
26
-
27
- const sats = parseInt(satoshis, 10);
28
- if (isNaN(sats) || sats <= 0) {
29
- return fail('satoshis must be a positive integer');
30
- }
31
-
32
- try {
33
- const payment = await buildDirectPayment(pubkey, sats, description || 'agent payment');
34
- return ok(payment);
35
- } catch (err) {
36
- return fail(err instanceof Error ? err.message : String(err));
37
- }
38
- }
39
-
40
- /**
41
- * Verify command: verify an incoming payment BEEF.
42
- */
43
- export async function cmdVerify(beefBase64: string | undefined): Promise<any> {
44
- if (!beefBase64) {
45
- return fail('Usage: verify <beef_base64>');
46
- }
47
-
48
- const BSVAgentWallet = await getBSVAgentWallet();
49
- const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
50
-
51
- try {
52
- const result = wallet.verifyPayment({ beef: beefBase64 });
53
- await wallet.destroy();
54
- return ok(result);
55
- } catch (err) {
56
- await wallet.destroy();
57
- return fail(err instanceof Error ? err.message : String(err));
58
- }
59
- }
60
-
61
- /**
62
- * Accept command: accept and internalize a payment.
63
- */
64
- export async function cmdAccept(
65
- beef: string | undefined,
66
- derivationPrefix: string | undefined,
67
- derivationSuffix: string | undefined,
68
- senderIdentityKey: string | undefined,
69
- description?: string
70
- ): Promise<any> {
71
- if (!beef || !derivationPrefix || !derivationSuffix || !senderIdentityKey) {
72
- return fail('Usage: accept <beef> <prefix> <suffix> <senderKey> [description]');
73
- }
74
-
75
- const BSVAgentWallet = await getBSVAgentWallet();
76
- const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
77
-
78
- try {
79
- const receipt = await wallet.acceptPayment({
80
- beef,
81
- derivationPrefix,
82
- derivationSuffix,
83
- senderIdentityKey,
84
- description: description || undefined,
85
- });
86
- await wallet.destroy();
87
- return ok(receipt);
88
- } catch (err) {
89
- await wallet.destroy();
90
- return fail(err instanceof Error ? err.message : String(err));
91
- }
92
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Payment module exports.
3
- */
4
-
5
- export * from './types.js';
6
- export * from './build.js';
7
- export * from './commands.js';
@@ -1,62 +0,0 @@
1
- /**
2
- * Payment-specific type definitions.
3
- */
4
-
5
- export interface PaymentResult {
6
- /** Base64-encoded Atomic BEEF transaction data */
7
- beef: string;
8
- /** Transaction ID (hex) */
9
- txid: string;
10
- /** Amount paid in satoshis */
11
- satoshis: number;
12
- /** BRC-29 derivation prefix (base64) - needed by recipient */
13
- derivationPrefix: string;
14
- /** BRC-29 derivation suffix (base64) - needed by recipient */
15
- derivationSuffix: string;
16
- /** Sender's identity key (compressed hex) - needed by recipient */
17
- senderIdentityKey: string;
18
- }
19
-
20
- export interface PaymentParams {
21
- /** Recipient's compressed public key (hex, 66 chars starting with 02/03) */
22
- to: string;
23
- /** Amount to pay in satoshis */
24
- satoshis: number;
25
- /** Optional human-readable description */
26
- description?: string;
27
- }
28
-
29
- export interface VerifyParams {
30
- /** Base64-encoded BEEF */
31
- beef: string;
32
- /** Expected amount (optional) */
33
- expectedAmount?: number;
34
- /** Expected sender identity key (optional) */
35
- expectedSender?: string;
36
- }
37
-
38
- export interface VerifyResult {
39
- valid: boolean;
40
- txid: string;
41
- outputCount: number;
42
- errors: string[];
43
- }
44
-
45
- export interface AcceptParams {
46
- /** Base64-encoded Atomic BEEF */
47
- beef: string;
48
- /** Output index (default: 0) */
49
- vout?: number;
50
- /** BRC-29 derivation prefix from PaymentResult */
51
- derivationPrefix: string;
52
- /** BRC-29 derivation suffix from PaymentResult */
53
- derivationSuffix: string;
54
- /** Sender's identity key from PaymentResult */
55
- senderIdentityKey: string;
56
- /** Optional description */
57
- description?: string;
58
- }
59
-
60
- export interface AcceptResult {
61
- accepted: boolean;
62
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Services module exports.
3
- */
4
-
5
- export * from './request.js';
6
- export * from './respond.js';
7
- export * from './queue.js';
@@ -1,35 +0,0 @@
1
- /**
2
- * Service queue commands.
3
- */
4
-
5
- import fs from 'node:fs';
6
- import { PATHS } from '../config.js';
7
- import { ok } from '../output.js';
8
- import { readJsonl } from '../utils/storage.js';
9
-
10
- /**
11
- * Service queue command: list pending service requests.
12
- */
13
- export async function cmdServiceQueue(): Promise<any> {
14
- if (!fs.existsSync(PATHS.serviceQueue)) {
15
- return ok({ pending: [], count: 0 });
16
- }
17
-
18
- const entries = readJsonl<any>(PATHS.serviceQueue);
19
- const pending = entries.filter(e => e.status === 'pending');
20
-
21
- return ok({ pending, count: pending.length, total: entries.length });
22
- }
23
-
24
- /**
25
- * Research queue command: list pending research requests.
26
- */
27
- export async function cmdResearchQueue(): Promise<any> {
28
- if (!fs.existsSync(PATHS.researchQueue)) {
29
- return ok({ pending: [] });
30
- }
31
-
32
- const entries = readJsonl<any>(PATHS.researchQueue);
33
-
34
- return ok({ pending: entries, count: entries.length });
35
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * Service request command.
3
- */
4
-
5
- import { OVERLAY_URL } from '../config.js';
6
- import { ok, fail } from '../output.js';
7
- import { loadIdentity, signRelayMessage } from '../wallet/identity.js';
8
- import { buildDirectPayment } from '../payment/build.js';
9
-
10
- /**
11
- * Request service command: send a service request with optional payment.
12
- */
13
- export async function cmdRequestService(
14
- targetKey: string | undefined,
15
- serviceId: string | undefined,
16
- satsStr?: string,
17
- inputJsonStr?: string
18
- ): Promise<any> {
19
- if (!targetKey || !serviceId) {
20
- return fail('Usage: request-service <identityKey> <serviceId> [sats] [inputJson]');
21
- }
22
-
23
- if (!/^0[23][0-9a-fA-F]{64}$/.test(targetKey)) {
24
- return fail('Target must be a compressed public key (66 hex chars, 02/03 prefix)');
25
- }
26
-
27
- const { identityKey, privKey } = await loadIdentity();
28
- const sats = parseInt(satsStr || '5', 10);
29
-
30
- // Parse optional input JSON
31
- let inputData: unknown = null;
32
- if (inputJsonStr) {
33
- try {
34
- inputData = JSON.parse(inputJsonStr);
35
- } catch {
36
- return fail('inputJson must be valid JSON');
37
- }
38
- }
39
-
40
- // Build the service request payload
41
- let paymentData: any = null;
42
-
43
- if (sats > 0) {
44
- try {
45
- const payment = await buildDirectPayment(targetKey, sats, `service-request: ${serviceId}`);
46
- paymentData = {
47
- beef: payment.beef,
48
- txid: payment.txid,
49
- satoshis: payment.satoshis,
50
- derivationPrefix: payment.derivationPrefix,
51
- derivationSuffix: payment.derivationSuffix,
52
- senderIdentityKey: payment.senderIdentityKey,
53
- };
54
- } catch (err: any) {
55
- // Payment failed — send request without payment
56
- paymentData = { error: String(err.message || err) };
57
- }
58
- }
59
-
60
- const requestPayload = {
61
- serviceId,
62
- ...(inputData ? { input: inputData } : {}),
63
- payment: paymentData,
64
- requestedAt: new Date().toISOString(),
65
- };
66
-
67
- const signature = await signRelayMessage(privKey, targetKey, 'service-request', requestPayload);
68
-
69
- const resp = await fetch(`${OVERLAY_URL}/relay/send`, {
70
- method: 'POST',
71
- headers: { 'Content-Type': 'application/json' },
72
- body: JSON.stringify({
73
- from: identityKey,
74
- to: targetKey,
75
- type: 'service-request',
76
- payload: requestPayload,
77
- signature,
78
- }),
79
- });
80
-
81
- if (!resp.ok) {
82
- const body = await resp.text();
83
- return fail(`Relay send failed (${resp.status}): ${body}`);
84
- }
85
-
86
- const result = await resp.json();
87
-
88
- return ok({
89
- sent: true,
90
- requestId: result.id,
91
- to: targetKey,
92
- serviceId,
93
- paymentIncluded: paymentData && !paymentData.error,
94
- paymentTxid: paymentData?.txid || null,
95
- satoshis: paymentData?.satoshis || 0,
96
- note: 'Poll for service-response to get the result',
97
- });
98
- }