openclaw-overlay-plugin 0.8.15 → 0.8.17
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/dist/index.js +3037 -328
- package/dist/index.js.map +7 -0
- package/dist/src/cli.js +3820 -11
- package/dist/src/cli.js.map +7 -0
- package/index.ts +32 -27
- package/openclaw.plugin.json +1 -1
- package/package.json +8 -6
- package/src/scripts/messaging/handlers.ts +1 -1
- package/src/scripts/overlay/advertisement.ts +1 -1
- package/src/scripts/overlay/registration.ts +1 -1
- package/src/scripts/overlay/services.ts +1 -1
- package/src/scripts/overlay/transaction.ts +1 -1
- package/src/scripts/payment/build.ts +1 -1
- package/src/scripts/payment/commands.ts +1 -1
- package/src/scripts/wallet/balance.ts +1 -1
- package/src/scripts/wallet/setup.ts +1 -1
- package/src/scripts/x-verification/commands.ts +5 -0
- package/src/test/identity-consistency.test.ts +1 -1
- package/src/test/wallet.test.ts +1 -2
- package/dist/index.d.ts +0 -9
- package/dist/src/cli-main.d.ts +0 -7
- package/dist/src/cli-main.js +0 -202
- package/dist/src/cli.d.ts +0 -8
- package/dist/src/compatibility.test.d.ts +0 -4
- package/dist/src/compatibility.test.js +0 -41
- package/dist/src/core/config.d.ts +0 -11
- package/dist/src/core/config.js +0 -15
- package/dist/src/core/index.d.ts +0 -25
- package/dist/src/core/index.js +0 -26
- package/dist/src/core/payment.d.ts +0 -16
- package/dist/src/core/payment.js +0 -94
- package/dist/src/core/types.d.ts +0 -94
- package/dist/src/core/types.js +0 -4
- package/dist/src/core/verify.d.ts +0 -28
- package/dist/src/core/verify.js +0 -104
- package/dist/src/core/wallet.d.ts +0 -105
- package/dist/src/core/wallet.js +0 -256
- package/dist/src/scripts/baemail/commands.d.ts +0 -35
- package/dist/src/scripts/baemail/commands.js +0 -282
- package/dist/src/scripts/baemail/handler.d.ts +0 -36
- package/dist/src/scripts/baemail/handler.js +0 -284
- package/dist/src/scripts/baemail/index.d.ts +0 -5
- package/dist/src/scripts/baemail/index.js +0 -5
- package/dist/src/scripts/config.d.ts +0 -52
- package/dist/src/scripts/config.js +0 -75
- package/dist/src/scripts/index.d.ts +0 -7
- package/dist/src/scripts/index.js +0 -7
- package/dist/src/scripts/messaging/connect.d.ts +0 -8
- package/dist/src/scripts/messaging/connect.js +0 -168
- package/dist/src/scripts/messaging/handlers.d.ts +0 -21
- package/dist/src/scripts/messaging/handlers.js +0 -334
- package/dist/src/scripts/messaging/inbox.d.ts +0 -11
- package/dist/src/scripts/messaging/inbox.js +0 -51
- package/dist/src/scripts/messaging/index.d.ts +0 -8
- package/dist/src/scripts/messaging/index.js +0 -8
- package/dist/src/scripts/messaging/poll.d.ts +0 -7
- package/dist/src/scripts/messaging/poll.js +0 -52
- package/dist/src/scripts/messaging/send.d.ts +0 -7
- package/dist/src/scripts/messaging/send.js +0 -43
- package/dist/src/scripts/output.d.ts +0 -13
- package/dist/src/scripts/output.js +0 -28
- package/dist/src/scripts/overlay/advertisement.d.ts +0 -16
- package/dist/src/scripts/overlay/advertisement.js +0 -122
- package/dist/src/scripts/overlay/discover.d.ts +0 -7
- package/dist/src/scripts/overlay/discover.js +0 -74
- package/dist/src/scripts/overlay/index.d.ts +0 -7
- package/dist/src/scripts/overlay/index.js +0 -7
- package/dist/src/scripts/overlay/registration.d.ts +0 -19
- package/dist/src/scripts/overlay/registration.js +0 -176
- package/dist/src/scripts/overlay/services.d.ts +0 -29
- package/dist/src/scripts/overlay/services.js +0 -167
- package/dist/src/scripts/overlay/transaction.d.ts +0 -42
- package/dist/src/scripts/overlay/transaction.js +0 -103
- package/dist/src/scripts/payment/build.d.ts +0 -24
- package/dist/src/scripts/payment/build.js +0 -54
- package/dist/src/scripts/payment/commands.d.ts +0 -15
- package/dist/src/scripts/payment/commands.js +0 -73
- package/dist/src/scripts/payment/index.d.ts +0 -6
- package/dist/src/scripts/payment/index.js +0 -6
- package/dist/src/scripts/payment/types.d.ts +0 -56
- package/dist/src/scripts/payment/types.js +0 -4
- package/dist/src/scripts/services/index.d.ts +0 -6
- package/dist/src/scripts/services/index.js +0 -6
- package/dist/src/scripts/services/queue.d.ts +0 -11
- package/dist/src/scripts/services/queue.js +0 -28
- package/dist/src/scripts/services/request.d.ts +0 -7
- package/dist/src/scripts/services/request.js +0 -82
- package/dist/src/scripts/services/respond.d.ts +0 -11
- package/dist/src/scripts/services/respond.js +0 -132
- package/dist/src/scripts/types.d.ts +0 -107
- package/dist/src/scripts/types.js +0 -4
- package/dist/src/scripts/utils/index.d.ts +0 -6
- package/dist/src/scripts/utils/index.js +0 -6
- package/dist/src/scripts/utils/merkle.d.ts +0 -12
- package/dist/src/scripts/utils/merkle.js +0 -47
- package/dist/src/scripts/utils/storage.d.ts +0 -66
- package/dist/src/scripts/utils/storage.js +0 -211
- package/dist/src/scripts/utils/woc.d.ts +0 -26
- package/dist/src/scripts/utils/woc.js +0 -91
- package/dist/src/scripts/wallet/balance.d.ts +0 -22
- package/dist/src/scripts/wallet/balance.js +0 -240
- package/dist/src/scripts/wallet/identity.d.ts +0 -71
- package/dist/src/scripts/wallet/identity.js +0 -152
- package/dist/src/scripts/wallet/index.d.ts +0 -6
- package/dist/src/scripts/wallet/index.js +0 -6
- package/dist/src/scripts/wallet/setup.d.ts +0 -19
- package/dist/src/scripts/wallet/setup.js +0 -119
- package/dist/src/scripts/x-verification/commands.d.ts +0 -27
- package/dist/src/scripts/x-verification/commands.js +0 -222
- package/dist/src/scripts/x-verification/index.d.ts +0 -4
- package/dist/src/scripts/x-verification/index.js +0 -4
- package/dist/src/services/built-in/api-proxy/index.d.ts +0 -6
- package/dist/src/services/built-in/api-proxy/index.js +0 -23
- package/dist/src/services/built-in/code-develop/index.d.ts +0 -6
- package/dist/src/services/built-in/code-develop/index.js +0 -23
- package/dist/src/services/built-in/code-review/index.d.ts +0 -10
- package/dist/src/services/built-in/code-review/index.js +0 -51
- package/dist/src/services/built-in/image-analysis/index.d.ts +0 -6
- package/dist/src/services/built-in/image-analysis/index.js +0 -33
- package/dist/src/services/built-in/memory-store/index.d.ts +0 -6
- package/dist/src/services/built-in/memory-store/index.js +0 -22
- package/dist/src/services/built-in/roulette/index.d.ts +0 -6
- package/dist/src/services/built-in/roulette/index.js +0 -27
- package/dist/src/services/built-in/summarize/index.d.ts +0 -6
- package/dist/src/services/built-in/summarize/index.js +0 -21
- package/dist/src/services/built-in/tell-joke/handler.d.ts +0 -7
- package/dist/src/services/built-in/tell-joke/handler.js +0 -122
- package/dist/src/services/built-in/tell-joke/index.d.ts +0 -9
- package/dist/src/services/built-in/tell-joke/index.js +0 -31
- package/dist/src/services/built-in/translate/index.d.ts +0 -6
- package/dist/src/services/built-in/translate/index.js +0 -21
- package/dist/src/services/built-in/web-research/index.d.ts +0 -9
- package/dist/src/services/built-in/web-research/index.js +0 -51
- package/dist/src/services/index.d.ts +0 -13
- package/dist/src/services/index.js +0 -14
- package/dist/src/services/loader.d.ts +0 -77
- package/dist/src/services/loader.js +0 -292
- package/dist/src/services/manager.d.ts +0 -86
- package/dist/src/services/manager.js +0 -255
- package/dist/src/services/registry.d.ts +0 -98
- package/dist/src/services/registry.js +0 -204
- package/dist/src/services/types.d.ts +0 -230
- package/dist/src/services/types.js +0 -30
- package/dist/src/test/cli.test.d.ts +0 -7
- package/dist/src/test/cli.test.js +0 -330
- package/dist/src/test/comprehensive-overlay.test.d.ts +0 -13
- package/dist/src/test/comprehensive-overlay.test.js +0 -593
- package/dist/src/test/identity-consistency.test.d.ts +0 -6
- package/dist/src/test/identity-consistency.test.js +0 -60
- package/dist/src/test/key-derivation.test.d.ts +0 -12
- package/dist/src/test/key-derivation.test.js +0 -86
- package/dist/src/test/network-address.test.d.ts +0 -9
- package/dist/src/test/network-address.test.js +0 -37
- package/dist/src/test/overlay-submit.test.d.ts +0 -10
- package/dist/src/test/overlay-submit.test.js +0 -460
- package/dist/src/test/request-response-flow.test.d.ts +0 -5
- package/dist/src/test/request-response-flow.test.js +0 -210
- package/dist/src/test/service-system.test.d.ts +0 -5
- package/dist/src/test/service-system.test.js +0 -190
- package/dist/src/test/taskflow.test.d.ts +0 -7
- package/dist/src/test/taskflow.test.js +0 -82
- package/dist/src/test/utils/server-logic.d.ts +0 -98
- package/dist/src/test/utils/server-logic.js +0 -286
- package/dist/src/test/wallet.test.d.ts +0 -7
- package/dist/src/test/wallet.test.js +0 -146
- package/src/core/README.md +0 -246
- package/src/core/config.d.ts +0 -12
- package/src/core/config.d.ts.map +0 -1
- package/src/core/config.js +0 -14
- package/src/core/config.js.map +0 -1
- package/src/core/config.ts +0 -22
- package/src/core/index.ts +0 -42
- package/src/core/payment.d.ts +0 -17
- package/src/core/payment.d.ts.map +0 -1
- package/src/core/payment.js +0 -95
- package/src/core/payment.js.map +0 -1
- package/src/core/payment.ts +0 -111
- package/src/core/types.d.ts +0 -95
- package/src/core/types.d.ts.map +0 -1
- package/src/core/types.js +0 -5
- package/src/core/types.js.map +0 -1
- package/src/core/types.ts +0 -102
- package/src/core/verify.d.ts +0 -29
- package/src/core/verify.d.ts.map +0 -1
- package/src/core/verify.js +0 -105
- package/src/core/verify.js.map +0 -1
- package/src/core/verify.ts +0 -119
- package/src/core/wallet.d.ts +0 -100
- package/src/core/wallet.d.ts.map +0 -1
- package/src/core/wallet.js.map +0 -1
- package/src/core/wallet.ts +0 -323
|
@@ -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>;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Inbox and ack commands.
|
|
3
|
-
*/
|
|
4
|
-
import { OVERLAY_URL } from '../config.js';
|
|
5
|
-
import { ok, fail } from '../output.js';
|
|
6
|
-
import { loadIdentity, verifyRelaySignature } from '../wallet/identity.js';
|
|
7
|
-
/**
|
|
8
|
-
* Inbox command: fetch pending messages.
|
|
9
|
-
*/
|
|
10
|
-
export async function cmdInbox(args) {
|
|
11
|
-
const { identityKey } = await loadIdentity();
|
|
12
|
-
let since = '';
|
|
13
|
-
for (let i = 0; i < args.length; i++) {
|
|
14
|
-
if (args[i] === '--since' && args[i + 1])
|
|
15
|
-
since = `&since=${args[++i]}`;
|
|
16
|
-
}
|
|
17
|
-
const resp = await fetch(`${OVERLAY_URL}/relay/inbox?identity=${identityKey}${since}`);
|
|
18
|
-
if (!resp.ok) {
|
|
19
|
-
const body = await resp.text();
|
|
20
|
-
return fail(`Relay inbox failed (${resp.status}): ${body}`);
|
|
21
|
-
}
|
|
22
|
-
const result = await resp.json();
|
|
23
|
-
// Verify signatures on received messages
|
|
24
|
-
const messages = await Promise.all(result.messages.map(async (msg) => ({
|
|
25
|
-
...msg,
|
|
26
|
-
signatureValid: msg.signature
|
|
27
|
-
? (await verifyRelaySignature(msg.from, msg.to, msg.type, msg.payload, msg.signature)).valid
|
|
28
|
-
: null,
|
|
29
|
-
})));
|
|
30
|
-
return ok({ messages, count: messages.length, identityKey });
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Ack command: acknowledge processed messages.
|
|
34
|
-
*/
|
|
35
|
-
export async function cmdAck(messageIds) {
|
|
36
|
-
if (!messageIds || messageIds.length === 0) {
|
|
37
|
-
return fail('Usage: ack <messageId> [messageId2 ...]');
|
|
38
|
-
}
|
|
39
|
-
const { identityKey } = await loadIdentity();
|
|
40
|
-
const resp = await fetch(`${OVERLAY_URL}/relay/ack`, {
|
|
41
|
-
method: 'POST',
|
|
42
|
-
headers: { 'Content-Type': 'application/json' },
|
|
43
|
-
body: JSON.stringify({ identity: identityKey, messageIds }),
|
|
44
|
-
});
|
|
45
|
-
if (!resp.ok) {
|
|
46
|
-
const body = await resp.text();
|
|
47
|
-
return fail(`Relay ack failed (${resp.status}): ${body}`);
|
|
48
|
-
}
|
|
49
|
-
const result = await resp.json();
|
|
50
|
-
return ok({ acked: result.acked, messageIds });
|
|
51
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Poll command: fetch and process all pending messages.
|
|
3
|
-
*/
|
|
4
|
-
import { OVERLAY_URL } from '../config.js';
|
|
5
|
-
import { ok, fail } from '../output.js';
|
|
6
|
-
import { loadIdentity } from '../wallet/identity.js';
|
|
7
|
-
import { processMessage } from './handlers.js';
|
|
8
|
-
/**
|
|
9
|
-
* Poll command: fetch all pending messages and process them.
|
|
10
|
-
*/
|
|
11
|
-
export async function cmdPoll() {
|
|
12
|
-
const { identityKey, privKey } = await loadIdentity();
|
|
13
|
-
// Fetch inbox
|
|
14
|
-
const inboxResp = await fetch(`${OVERLAY_URL}/relay/inbox?identity=${identityKey}`);
|
|
15
|
-
if (!inboxResp.ok) {
|
|
16
|
-
const body = await inboxResp.text();
|
|
17
|
-
return fail(`Relay inbox failed (${inboxResp.status}): ${body}`);
|
|
18
|
-
}
|
|
19
|
-
const inbox = await inboxResp.json();
|
|
20
|
-
if (inbox.count === 0) {
|
|
21
|
-
return ok({ processed: 0, messages: [], summary: 'No pending messages.' });
|
|
22
|
-
}
|
|
23
|
-
const processed = [];
|
|
24
|
-
const ackedIds = [];
|
|
25
|
-
const unhandled = [];
|
|
26
|
-
for (const msg of inbox.messages) {
|
|
27
|
-
const result = await processMessage(msg, identityKey, privKey);
|
|
28
|
-
if (result.ack) {
|
|
29
|
-
ackedIds.push(result.id);
|
|
30
|
-
processed.push(result);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
unhandled.push(result);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
// ACK processed messages
|
|
37
|
-
if (ackedIds.length > 0) {
|
|
38
|
-
await fetch(`${OVERLAY_URL}/relay/ack`, {
|
|
39
|
-
method: 'POST',
|
|
40
|
-
headers: { 'Content-Type': 'application/json' },
|
|
41
|
-
body: JSON.stringify({ identity: identityKey, messageIds: ackedIds }),
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return ok({
|
|
45
|
-
processed: processed.length,
|
|
46
|
-
unhandled: unhandled.length,
|
|
47
|
-
total: inbox.count,
|
|
48
|
-
messages: processed,
|
|
49
|
-
unhandledMessages: unhandled,
|
|
50
|
-
ackedIds,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Send relay message command.
|
|
3
|
-
*/
|
|
4
|
-
import { OVERLAY_URL } from '../config.js';
|
|
5
|
-
import { ok, fail } from '../output.js';
|
|
6
|
-
import { loadIdentity, signRelayMessage } from '../wallet/identity.js';
|
|
7
|
-
/**
|
|
8
|
-
* Send command: send a typed message to another agent.
|
|
9
|
-
*/
|
|
10
|
-
export async function cmdSend(targetKey, type, payloadStr) {
|
|
11
|
-
if (!targetKey || !type || !payloadStr) {
|
|
12
|
-
return fail('Usage: send <identityKey> <type> <json_payload>');
|
|
13
|
-
}
|
|
14
|
-
if (!/^0[23][0-9a-fA-F]{64}$/.test(targetKey)) {
|
|
15
|
-
return fail('Target must be a compressed public key (66 hex chars, 02/03 prefix)');
|
|
16
|
-
}
|
|
17
|
-
let payload;
|
|
18
|
-
try {
|
|
19
|
-
payload = JSON.parse(payloadStr);
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return fail('payload must be valid JSON');
|
|
23
|
-
}
|
|
24
|
-
const { identityKey, privKey } = await loadIdentity();
|
|
25
|
-
const signature = await signRelayMessage(privKey, targetKey, type, payload);
|
|
26
|
-
const resp = await fetch(`${OVERLAY_URL}/relay/send`, {
|
|
27
|
-
method: 'POST',
|
|
28
|
-
headers: { 'Content-Type': 'application/json' },
|
|
29
|
-
body: JSON.stringify({
|
|
30
|
-
from: identityKey,
|
|
31
|
-
to: targetKey,
|
|
32
|
-
type,
|
|
33
|
-
payload,
|
|
34
|
-
signature,
|
|
35
|
-
}),
|
|
36
|
-
});
|
|
37
|
-
if (!resp.ok) {
|
|
38
|
-
const body = await resp.text();
|
|
39
|
-
return fail(`Relay send failed (${resp.status}): ${body}`);
|
|
40
|
-
}
|
|
41
|
-
const result = await resp.json();
|
|
42
|
-
return ok({ sent: true, messageId: result.id, to: targetKey, type, signed: true });
|
|
43
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON output helpers for CLI commands.
|
|
3
|
-
* All CLI output follows the { success, data/error } wrapper format.
|
|
4
|
-
*/
|
|
5
|
-
export declare function setNoExit(value: boolean): void;
|
|
6
|
-
/**
|
|
7
|
-
* Output a successful result and exit (unless noExit is set).
|
|
8
|
-
*/
|
|
9
|
-
export declare function ok<T>(data: T): any;
|
|
10
|
-
/**
|
|
11
|
-
* Output an error and exit (unless noExit is set).
|
|
12
|
-
*/
|
|
13
|
-
export declare function fail(error: string | Error): any;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON output helpers for CLI commands.
|
|
3
|
-
* All CLI output follows the { success, data/error } wrapper format.
|
|
4
|
-
*/
|
|
5
|
-
// Global flag to prevent exit when used as a library
|
|
6
|
-
let noExitFlag = false;
|
|
7
|
-
export function setNoExit(value) {
|
|
8
|
-
noExitFlag = value;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Output a successful result and exit (unless noExit is set).
|
|
12
|
-
*/
|
|
13
|
-
export function ok(data) {
|
|
14
|
-
if (noExitFlag)
|
|
15
|
-
return { success: true, data };
|
|
16
|
-
console.log(JSON.stringify({ success: true, data }));
|
|
17
|
-
process.exit(0);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Output an error and exit (unless noExit is set).
|
|
21
|
-
*/
|
|
22
|
-
export function fail(error) {
|
|
23
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
24
|
-
if (noExitFlag)
|
|
25
|
-
return { success: false, error: message };
|
|
26
|
-
console.log(JSON.stringify({ success: false, error: message }));
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SHIP and SLAP advertisement commands.
|
|
3
|
-
*
|
|
4
|
-
* SHIP: Service Health & Information Protocol (tm_ship)
|
|
5
|
-
* SLAP: Service Level Agreement Protocol (tm_slap)
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Advertise a SHIP record.
|
|
9
|
-
* Announce that you host a specific Topic Manager (tm_).
|
|
10
|
-
*/
|
|
11
|
-
export declare function cmdAdvertiseSHIP(domain?: string, topic?: string): Promise<any>;
|
|
12
|
-
/**
|
|
13
|
-
* Advertise a SLAP record.
|
|
14
|
-
* Announce that you host a specific Lookup Service (ls_).
|
|
15
|
-
*/
|
|
16
|
-
export declare function cmdAdvertiseSLAP(domain?: string, service?: string): Promise<any>;
|