@lawreneliang/atel-sdk 0.3.2 → 0.4.0
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/bin/atel.mjs +139 -271
- package/dist/anchor/base.js +1 -1
- package/dist/anchor/bsc.js +1 -1
- package/dist/anchor/evm.js +1 -1
- package/dist/anchor/index.js +1 -1
- package/dist/anchor/mock.js +1 -1
- package/dist/anchor/solana.js +1 -1
- package/dist/collaboration/index.js +1 -1
- package/dist/crypto/index.js +1 -1
- package/dist/endpoint/index.js +1 -1
- package/dist/envelope/index.js +1 -1
- package/dist/gateway/index.js +1 -1
- package/dist/graph/index.js +1 -1
- package/dist/handshake/index.js +1 -1
- package/dist/identity/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/negotiation/index.js +1 -1
- package/dist/orchestrator/index.js +1 -1
- package/dist/policy/index.js +1 -1
- package/dist/proof/index.js +1 -1
- package/dist/registry/index.js +1 -1
- package/dist/rollback/index.js +1 -1
- package/dist/score/index.js +1 -1
- package/dist/service/index.js +1 -1
- package/dist/service/server.js +1 -1
- package/dist/trace/index.js +1 -1
- package/dist/trust/index.js +1 -1
- package/dist/trust-sync/index.js +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +42 -33
package/bin/atel.mjs
CHANGED
|
@@ -3,45 +3,42 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* ATEL CLI — Command-line interface for ATEL SDK
|
|
5
5
|
*
|
|
6
|
+
* All agent communication goes through the Relay server.
|
|
7
|
+
* Agents never expose their IP or open ports.
|
|
8
|
+
*
|
|
6
9
|
* Commands:
|
|
7
|
-
* atel init
|
|
8
|
-
* atel
|
|
9
|
-
* atel register
|
|
10
|
-
* atel search <capability>
|
|
11
|
-
* atel
|
|
12
|
-
* atel
|
|
13
|
-
* atel
|
|
10
|
+
* atel init [name] Create a new agent identity
|
|
11
|
+
* atel info Show current agent identity
|
|
12
|
+
* atel register [name] [caps] Register on the public registry
|
|
13
|
+
* atel search <capability> Search registry for agents
|
|
14
|
+
* atel send <did> <json> Send a message to an agent (via relay)
|
|
15
|
+
* atel listen Listen for incoming messages (via relay long-poll)
|
|
16
|
+
* atel inbox [count] Show received messages from local inbox
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, appendFileSync } from 'node:fs';
|
|
17
20
|
import { resolve } from 'node:path';
|
|
18
21
|
import {
|
|
19
22
|
AgentIdentity,
|
|
20
|
-
AgentEndpoint,
|
|
21
|
-
AgentClient,
|
|
22
|
-
HandshakeManager,
|
|
23
23
|
createMessage,
|
|
24
24
|
RegistryClient,
|
|
25
25
|
ExecutionTrace,
|
|
26
26
|
ProofGenerator,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
mintConsentToken,
|
|
27
|
+
sign,
|
|
28
|
+
serializePayload,
|
|
30
29
|
} from '@lawreneliang/atel-sdk';
|
|
31
30
|
|
|
32
31
|
const ATEL_DIR = resolve(process.env.ATEL_DIR || '.atel');
|
|
33
32
|
const IDENTITY_FILE = resolve(ATEL_DIR, 'identity.json');
|
|
34
33
|
const REGISTRY_URL = process.env.ATEL_REGISTRY || 'http://47.251.8.19:8100';
|
|
34
|
+
const RELAY_URL = process.env.ATEL_RELAY || REGISTRY_URL;
|
|
35
35
|
const WEBHOOK_URL = process.env.ATEL_WEBHOOK || '';
|
|
36
36
|
const INBOX_FILE = resolve(ATEL_DIR, 'inbox.jsonl');
|
|
37
37
|
|
|
38
|
-
// ───
|
|
38
|
+
// ─── Helpers ─────────────────────────────────────────────────────
|
|
39
39
|
|
|
40
40
|
async function notify(event) {
|
|
41
|
-
// Always append to inbox file
|
|
42
41
|
appendFileSync(INBOX_FILE, JSON.stringify(event) + '\n');
|
|
43
|
-
|
|
44
|
-
// Send webhook if configured
|
|
45
42
|
if (WEBHOOK_URL) {
|
|
46
43
|
try {
|
|
47
44
|
await fetch(WEBHOOK_URL, {
|
|
@@ -55,17 +52,14 @@ async function notify(event) {
|
|
|
55
52
|
}
|
|
56
53
|
}
|
|
57
54
|
|
|
58
|
-
// ─── Identity Persistence ────────────────────────────────────────
|
|
59
|
-
|
|
60
55
|
function saveIdentity(identity) {
|
|
61
56
|
if (!existsSync(ATEL_DIR)) mkdirSync(ATEL_DIR, { recursive: true });
|
|
62
|
-
|
|
57
|
+
writeFileSync(IDENTITY_FILE, JSON.stringify({
|
|
63
58
|
agent_id: identity.agent_id,
|
|
64
59
|
did: identity.did,
|
|
65
60
|
publicKey: Buffer.from(identity.publicKey).toString('hex'),
|
|
66
61
|
secretKey: Buffer.from(identity.secretKey).toString('hex'),
|
|
67
|
-
};
|
|
68
|
-
writeFileSync(IDENTITY_FILE, JSON.stringify(data, null, 2));
|
|
62
|
+
}, null, 2));
|
|
69
63
|
}
|
|
70
64
|
|
|
71
65
|
function loadIdentity() {
|
|
@@ -80,13 +74,44 @@ function loadIdentity() {
|
|
|
80
74
|
|
|
81
75
|
function requireIdentity() {
|
|
82
76
|
const id = loadIdentity();
|
|
83
|
-
if (!id) {
|
|
84
|
-
console.error('No identity found. Run: atel init');
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
77
|
+
if (!id) { console.error('No identity found. Run: atel init'); process.exit(1); }
|
|
87
78
|
return id;
|
|
88
79
|
}
|
|
89
80
|
|
|
81
|
+
// ─── Relay Communication ─────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
async function relaySend(id, toDid, type, payload) {
|
|
84
|
+
const msg = createMessage({ type, from: id.did, to: toDid, payload, secretKey: id.secretKey });
|
|
85
|
+
const response = await fetch(`${RELAY_URL}/relay/v1/send`, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
body: JSON.stringify(msg),
|
|
89
|
+
});
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
const err = await response.json().catch(() => ({ error: response.statusText }));
|
|
92
|
+
throw new Error(err.error || `Relay send failed: ${response.status}`);
|
|
93
|
+
}
|
|
94
|
+
return response.json();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function relayPoll(id) {
|
|
98
|
+
const timestamp = new Date().toISOString();
|
|
99
|
+
const payload = { action: 'poll' };
|
|
100
|
+
const signable = serializePayload({ payload, did: id.did, timestamp });
|
|
101
|
+
const signature = sign(signable, id.secretKey);
|
|
102
|
+
const pollBody = { did: id.did, timestamp, payload, signature };
|
|
103
|
+
const response = await fetch(`${RELAY_URL}/relay/v1/poll`, {
|
|
104
|
+
method: 'POST',
|
|
105
|
+
headers: { 'Content-Type': 'application/json' },
|
|
106
|
+
body: JSON.stringify(pollBody),
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
const err = await response.json().catch(() => ({ error: response.statusText }));
|
|
110
|
+
throw new Error(err.error || `Relay poll failed: ${response.status}`);
|
|
111
|
+
}
|
|
112
|
+
return response.json();
|
|
113
|
+
}
|
|
114
|
+
|
|
90
115
|
// ─── Commands ────────────────────────────────────────────────────
|
|
91
116
|
|
|
92
117
|
async function cmdInit(agentId) {
|
|
@@ -97,195 +122,27 @@ async function cmdInit(agentId) {
|
|
|
97
122
|
status: 'created',
|
|
98
123
|
agent_id: identity.agent_id,
|
|
99
124
|
did: identity.did,
|
|
100
|
-
|
|
125
|
+
next: 'Run: atel register to join the network',
|
|
101
126
|
}, null, 2));
|
|
102
127
|
}
|
|
103
128
|
|
|
104
129
|
async function cmdInfo() {
|
|
105
130
|
const id = requireIdentity();
|
|
106
|
-
console.log(JSON.stringify({
|
|
107
|
-
agent_id: id.agent_id,
|
|
108
|
-
did: id.did,
|
|
109
|
-
}, null, 2));
|
|
131
|
+
console.log(JSON.stringify({ agent_id: id.agent_id, did: id.did }, null, 2));
|
|
110
132
|
}
|
|
111
133
|
|
|
112
|
-
async function
|
|
113
|
-
const id = requireIdentity();
|
|
114
|
-
const p = parseInt(port || '3100');
|
|
115
|
-
const endpoint = new AgentEndpoint(id, { port: p, host: '0.0.0.0' });
|
|
116
|
-
|
|
117
|
-
// Load task handlers from .atel/tools.json if exists
|
|
118
|
-
const toolsFile = resolve(ATEL_DIR, 'tools.json');
|
|
119
|
-
const registeredTools = {};
|
|
120
|
-
if (existsSync(toolsFile)) {
|
|
121
|
-
try {
|
|
122
|
-
const toolsDef = JSON.parse(readFileSync(toolsFile, 'utf-8'));
|
|
123
|
-
for (const [name, def] of Object.entries(toolsDef)) {
|
|
124
|
-
registeredTools[name] = async (input) => {
|
|
125
|
-
// Shell-based tool execution
|
|
126
|
-
const { execSync } = await import('node:child_process');
|
|
127
|
-
const cmd = def.command.replace('{{input}}', JSON.stringify(input));
|
|
128
|
-
const output = execSync(cmd, { encoding: 'utf-8', timeout: 30000 });
|
|
129
|
-
return JSON.parse(output);
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
} catch (e) {
|
|
133
|
-
console.error(JSON.stringify({ event: 'tools_load_error', error: e.message }));
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
endpoint.onTask(async (message, session) => {
|
|
138
|
-
const taskEvent = {
|
|
139
|
-
event: 'task_received',
|
|
140
|
-
from: message.from,
|
|
141
|
-
type: message.type,
|
|
142
|
-
payload: message.payload,
|
|
143
|
-
encrypted: !!session?.encrypted,
|
|
144
|
-
timestamp: new Date().toISOString(),
|
|
145
|
-
};
|
|
146
|
-
console.log(JSON.stringify(taskEvent));
|
|
147
|
-
await notify(taskEvent);
|
|
148
|
-
|
|
149
|
-
// ── Full ATEL execution flow: Trace → Gateway → Proof ──
|
|
150
|
-
const trace = new ExecutionTrace(
|
|
151
|
-
`task-${Date.now()}`,
|
|
152
|
-
id,
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
trace.append('TASK_RECEIVED', {
|
|
156
|
-
from: message.from,
|
|
157
|
-
payload: message.payload,
|
|
158
|
-
encrypted: !!session?.encrypted,
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
let result;
|
|
162
|
-
let success = true;
|
|
163
|
-
|
|
164
|
-
try {
|
|
165
|
-
const payload = message.payload || {};
|
|
166
|
-
const action = payload.action || payload.type || 'unknown';
|
|
167
|
-
|
|
168
|
-
// If we have registered tools matching the action, use Gateway
|
|
169
|
-
if (registeredTools[action]) {
|
|
170
|
-
const consentToken = mintConsentToken(
|
|
171
|
-
message.from, id.did,
|
|
172
|
-
[action],
|
|
173
|
-
{ max_calls: 10, ttl_sec: 300 },
|
|
174
|
-
'low',
|
|
175
|
-
id.secretKey,
|
|
176
|
-
);
|
|
177
|
-
const policyEngine = new PolicyEngine(consentToken);
|
|
178
|
-
const gateway = new ToolGateway(policyEngine, {
|
|
179
|
-
trace,
|
|
180
|
-
defaultRiskLevel: 'low',
|
|
181
|
-
});
|
|
182
|
-
gateway.registerTool(action, registeredTools[action]);
|
|
183
|
-
|
|
184
|
-
result = await gateway.call(action, payload);
|
|
185
|
-
trace.append('TOOL_EXECUTED', { action, result });
|
|
186
|
-
} else {
|
|
187
|
-
// Default: echo back with acknowledgment
|
|
188
|
-
result = {
|
|
189
|
-
status: 'processed',
|
|
190
|
-
agent: id.agent_id,
|
|
191
|
-
action,
|
|
192
|
-
message: `Task received and logged. Action "${action}" has no registered handler.`,
|
|
193
|
-
received_payload: payload,
|
|
194
|
-
};
|
|
195
|
-
trace.append('TASK_NO_HANDLER', { action, available_tools: Object.keys(registeredTools) });
|
|
196
|
-
}
|
|
197
|
-
} catch (err) {
|
|
198
|
-
success = false;
|
|
199
|
-
result = { status: 'error', error: err.message };
|
|
200
|
-
trace.fail(err);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Finalize trace
|
|
204
|
-
if (success && !trace.isFinalized() && !trace.isFailed()) {
|
|
205
|
-
trace.finalize(typeof result === 'object' ? result : { result });
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Generate cryptographic proof
|
|
209
|
-
const proofGen = new ProofGenerator(trace, id);
|
|
210
|
-
const proof = proofGen.generateFromContext({
|
|
211
|
-
taskResult: result,
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
const completionEvent = {
|
|
215
|
-
event: 'task_completed',
|
|
216
|
-
from: message.from,
|
|
217
|
-
success,
|
|
218
|
-
proof_id: proof.proof_id,
|
|
219
|
-
trace_root: proof.trace_root,
|
|
220
|
-
timestamp: new Date().toISOString(),
|
|
221
|
-
};
|
|
222
|
-
console.log(JSON.stringify(completionEvent));
|
|
223
|
-
await notify(completionEvent);
|
|
224
|
-
|
|
225
|
-
return { status: success ? 'completed' : 'failed', result, proof };
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
endpoint.onProof(async (message, session) => {
|
|
229
|
-
const proofEvent = {
|
|
230
|
-
event: 'proof_received',
|
|
231
|
-
from: message.from,
|
|
232
|
-
payload: message.payload,
|
|
233
|
-
timestamp: new Date().toISOString(),
|
|
234
|
-
};
|
|
235
|
-
console.log(JSON.stringify(proofEvent));
|
|
236
|
-
await notify(proofEvent);
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
await endpoint.start();
|
|
240
|
-
const startEvent = {
|
|
241
|
-
status: 'listening',
|
|
242
|
-
agent_id: id.agent_id,
|
|
243
|
-
did: id.did,
|
|
244
|
-
endpoint: endpoint.getEndpointUrl(),
|
|
245
|
-
port: p,
|
|
246
|
-
tools: Object.keys(registeredTools),
|
|
247
|
-
inbox: INBOX_FILE,
|
|
248
|
-
webhook: WEBHOOK_URL || 'not configured (set ATEL_WEBHOOK)',
|
|
249
|
-
};
|
|
250
|
-
console.log(JSON.stringify(startEvent, null, 2));
|
|
251
|
-
|
|
252
|
-
// Keep alive
|
|
253
|
-
process.on('SIGINT', async () => {
|
|
254
|
-
await endpoint.stop();
|
|
255
|
-
process.exit(0);
|
|
256
|
-
});
|
|
257
|
-
process.on('SIGTERM', async () => {
|
|
258
|
-
await endpoint.stop();
|
|
259
|
-
process.exit(0);
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
async function cmdInbox(count) {
|
|
264
|
-
const n = parseInt(count || '20');
|
|
265
|
-
if (!existsSync(INBOX_FILE)) {
|
|
266
|
-
console.log(JSON.stringify({ messages: [], count: 0 }));
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
const lines = readFileSync(INBOX_FILE, 'utf-8').trim().split('\n').filter(Boolean);
|
|
270
|
-
const messages = lines.slice(-n).map(l => JSON.parse(l));
|
|
271
|
-
console.log(JSON.stringify({ messages, count: messages.length, total: lines.length }, null, 2));
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
async function cmdRegister(name, capabilities, endpointUrl) {
|
|
134
|
+
async function cmdRegister(name, capabilities) {
|
|
275
135
|
const id = requireIdentity();
|
|
276
136
|
const client = new RegistryClient({ registryUrl: REGISTRY_URL });
|
|
277
|
-
|
|
278
137
|
const caps = (capabilities || 'general').split(',').map(c => ({
|
|
279
|
-
type: c.trim(),
|
|
280
|
-
description: c.trim(),
|
|
138
|
+
type: c.trim(), description: c.trim(),
|
|
281
139
|
}));
|
|
282
|
-
|
|
140
|
+
// Register via relay — no IP/endpoint needed
|
|
283
141
|
const entry = await client.register({
|
|
284
142
|
name: name || id.agent_id,
|
|
285
143
|
capabilities: caps,
|
|
286
|
-
endpoint:
|
|
144
|
+
endpoint: `relay://${id.did}`,
|
|
287
145
|
}, id);
|
|
288
|
-
|
|
289
146
|
console.log(JSON.stringify({
|
|
290
147
|
status: 'registered',
|
|
291
148
|
did: entry.did,
|
|
@@ -300,73 +157,84 @@ async function cmdSearch(capability) {
|
|
|
300
157
|
console.log(JSON.stringify(result, null, 2));
|
|
301
158
|
}
|
|
302
159
|
|
|
303
|
-
async function
|
|
160
|
+
async function cmdSend(toDid, taskJson) {
|
|
304
161
|
const id = requireIdentity();
|
|
305
|
-
const client = new AgentClient(id);
|
|
306
|
-
const hsManager = new HandshakeManager(id);
|
|
307
|
-
|
|
308
|
-
// If no DID provided, fetch from health endpoint
|
|
309
|
-
let did = remoteDid;
|
|
310
|
-
if (!did) {
|
|
311
|
-
const health = await client.health(remoteEndpoint);
|
|
312
|
-
did = health.did;
|
|
313
|
-
}
|
|
314
162
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
163
|
+
// If toDid looks like a capability, search registry first
|
|
164
|
+
if (!toDid.startsWith('did:')) {
|
|
165
|
+
const client = new RegistryClient({ registryUrl: REGISTRY_URL });
|
|
166
|
+
const result = await client.search({ type: toDid, limit: 1 });
|
|
167
|
+
if (result.count === 0) {
|
|
168
|
+
console.error(JSON.stringify({ error: `No agent found with capability: ${toDid}` }));
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
toDid = result.agents[0].did;
|
|
172
|
+
console.error(JSON.stringify({ info: `Found agent: ${result.agents[0].name} (${toDid})` }));
|
|
173
|
+
}
|
|
322
174
|
|
|
323
|
-
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
if (existsSync(sessFile)) sessions = JSON.parse(readFileSync(sessFile, 'utf-8'));
|
|
327
|
-
sessions[remoteEndpoint] = { did, sessionId: session.sessionId, encrypted: session.encrypted };
|
|
328
|
-
writeFileSync(sessFile, JSON.stringify(sessions, null, 2));
|
|
175
|
+
const payload = typeof taskJson === 'string' ? JSON.parse(taskJson) : taskJson;
|
|
176
|
+
const result = await relaySend(id, toDid, 'task', payload);
|
|
177
|
+
console.log(JSON.stringify({ status: 'sent', to: toDid, relay: result }, null, 2));
|
|
329
178
|
}
|
|
330
179
|
|
|
331
|
-
async function
|
|
180
|
+
async function cmdListen() {
|
|
332
181
|
const id = requireIdentity();
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
182
|
+
console.log(JSON.stringify({
|
|
183
|
+
status: 'listening',
|
|
184
|
+
agent_id: id.agent_id,
|
|
185
|
+
did: id.did,
|
|
186
|
+
relay: RELAY_URL,
|
|
187
|
+
mode: 'long-poll',
|
|
188
|
+
}, null, 2));
|
|
189
|
+
|
|
190
|
+
// Continuous long-poll loop
|
|
191
|
+
while (true) {
|
|
192
|
+
try {
|
|
193
|
+
const result = await relayPoll(id);
|
|
194
|
+
if (result.messages && result.messages.length > 0) {
|
|
195
|
+
for (const msg of result.messages) {
|
|
196
|
+
const event = {
|
|
197
|
+
event: 'message_received',
|
|
198
|
+
from: msg.from,
|
|
199
|
+
type: msg.type,
|
|
200
|
+
payload: msg.payload,
|
|
201
|
+
timestamp: new Date().toISOString(),
|
|
202
|
+
};
|
|
203
|
+
console.log(JSON.stringify(event));
|
|
204
|
+
await notify(event);
|
|
205
|
+
|
|
206
|
+
// Generate trace + proof for received tasks
|
|
207
|
+
if (msg.type === 'task') {
|
|
208
|
+
const trace = new ExecutionTrace(`task-${Date.now()}`, id);
|
|
209
|
+
trace.append('TASK_RECEIVED', { from: msg.from, payload: msg.payload });
|
|
210
|
+
trace.finalize({ status: 'received', from: msg.from });
|
|
211
|
+
const proofGen = new ProofGenerator(trace, id);
|
|
212
|
+
const proof = proofGen.generate('relay', `from-${msg.from}`, JSON.stringify(msg.payload));
|
|
213
|
+
console.log(JSON.stringify({
|
|
214
|
+
event: 'proof_generated',
|
|
215
|
+
proof_id: proof.proof_id,
|
|
216
|
+
trace_root: proof.trace_root,
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} catch (err) {
|
|
222
|
+
console.error(JSON.stringify({ event: 'poll_error', error: err.message }));
|
|
223
|
+
// Wait before retry
|
|
224
|
+
await new Promise(r => setTimeout(r, 5000));
|
|
343
225
|
}
|
|
344
226
|
}
|
|
227
|
+
}
|
|
345
228
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
// Save session
|
|
352
|
-
let sessions = {};
|
|
353
|
-
if (existsSync(sessFile)) sessions = JSON.parse(readFileSync(sessFile, 'utf-8'));
|
|
354
|
-
sessions[remoteEndpoint] = { did: remoteDid, sessionId: session.sessionId, encrypted: session.encrypted };
|
|
355
|
-
writeFileSync(sessFile, JSON.stringify(sessions, null, 2));
|
|
356
|
-
} else {
|
|
357
|
-
// Re-handshake (sessions are in-memory only for HandshakeManager)
|
|
358
|
-
await client.handshake(remoteEndpoint, hsManager, remoteDid);
|
|
229
|
+
async function cmdInbox(count) {
|
|
230
|
+
const n = parseInt(count || '20');
|
|
231
|
+
if (!existsSync(INBOX_FILE)) {
|
|
232
|
+
console.log(JSON.stringify({ messages: [], count: 0 }));
|
|
233
|
+
return;
|
|
359
234
|
}
|
|
360
|
-
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
const result = await client.sendTask(remoteEndpoint, msg, hsManager);
|
|
364
|
-
|
|
365
|
-
console.log(JSON.stringify({
|
|
366
|
-
status: 'task_sent',
|
|
367
|
-
remoteDid,
|
|
368
|
-
result,
|
|
369
|
-
}, null, 2));
|
|
235
|
+
const lines = readFileSync(INBOX_FILE, 'utf-8').trim().split('\n').filter(Boolean);
|
|
236
|
+
const messages = lines.slice(-n).map(l => JSON.parse(l));
|
|
237
|
+
console.log(JSON.stringify({ messages, count: messages.length, total: lines.length }, null, 2));
|
|
370
238
|
}
|
|
371
239
|
|
|
372
240
|
// ─── Main ────────────────────────────────────────────────────────
|
|
@@ -376,12 +244,11 @@ const [,, cmd, ...args] = process.argv;
|
|
|
376
244
|
const commands = {
|
|
377
245
|
init: () => cmdInit(args[0]),
|
|
378
246
|
info: () => cmdInfo(),
|
|
379
|
-
|
|
380
|
-
inbox: () => cmdInbox(args[0]),
|
|
381
|
-
register: () => cmdRegister(args[0], args[1], args[2]),
|
|
247
|
+
register: () => cmdRegister(args[0], args[1]),
|
|
382
248
|
search: () => cmdSearch(args[0]),
|
|
383
|
-
|
|
384
|
-
|
|
249
|
+
send: () => cmdSend(args[0], args[1]),
|
|
250
|
+
listen: () => cmdListen(),
|
|
251
|
+
inbox: () => cmdInbox(args[0]),
|
|
385
252
|
};
|
|
386
253
|
|
|
387
254
|
if (!cmd || !commands[cmd]) {
|
|
@@ -390,19 +257,20 @@ if (!cmd || !commands[cmd]) {
|
|
|
390
257
|
Usage: atel <command> [args]
|
|
391
258
|
|
|
392
259
|
Commands:
|
|
393
|
-
init [name]
|
|
394
|
-
info
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
task <endpoint> <json> Delegate task to remote agent
|
|
260
|
+
init [name] Create agent identity
|
|
261
|
+
info Show agent identity
|
|
262
|
+
register [name] [caps] Register on public registry (no IP needed)
|
|
263
|
+
search <capability> Search registry for agents
|
|
264
|
+
send <did|capability> <json> Send task to agent via relay
|
|
265
|
+
listen Listen for messages via relay (long-poll)
|
|
266
|
+
inbox [count] Show received messages (default: 20)
|
|
401
267
|
|
|
402
268
|
Environment:
|
|
403
269
|
ATEL_DIR Identity directory (default: .atel)
|
|
404
270
|
ATEL_REGISTRY Registry URL (default: http://47.251.8.19:8100)
|
|
405
|
-
ATEL_WEBHOOK Webhook URL for
|
|
271
|
+
ATEL_WEBHOOK Webhook URL for notifications (optional)
|
|
272
|
+
|
|
273
|
+
No ports, no IP exposure. All communication goes through the relay.`);
|
|
406
274
|
process.exit(cmd ? 1 : 0);
|
|
407
275
|
}
|
|
408
276
|
|
package/dist/anchor/base.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var _0x1dd0de=_0x28da;(function(_0x12ae13,_0x409752){var _0x352e8f=_0x28da,_0x571321=_0x12ae13();while(!![]){try{var _0x4193b8=parseInt(_0x352e8f(0x16d))/0x1*(-parseInt(_0x352e8f(0x172))/0x2)+parseInt(_0x352e8f(0x16a))/0x3+-parseInt(_0x352e8f(0x174))/0x4*(parseInt(_0x352e8f(0x175))/0x5)+-parseInt(_0x352e8f(0x170))/0x6*(-parseInt(_0x352e8f(0x16c))/0x7)+-parseInt(_0x352e8f(0x16b))/0x8+parseInt(_0x352e8f(0x167))/0x9*(-parseInt(_0x352e8f(0x166))/0xa)+parseInt(_0x352e8f(0x168))/0xb*(parseInt(_0x352e8f(0x171))/0xc);if(_0x4193b8===_0x409752)break;else _0x571321['push'](_0x571321['shift']());}catch(_0x20428d){_0x571321['push'](_0x571321['shift']());}}}(_0x116f,0x27ebf));function _0x28da(_0x4bd54d,_0x1e9d29){_0x4bd54d=_0x4bd54d-0x166;var _0x116f5a=_0x116f();var _0x28da9e=_0x116f5a[_0x4bd54d];if(_0x28da['kEOyTe']===undefined){var _0x4688d2=function(_0x15e417){var _0x3b5848='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0xa1ceb8='',_0xe05a42='';for(var _0x4ed789=0x0,_0x24d925,_0x29a5b8,_0xd566c4=0x0;_0x29a5b8=_0x15e417['charAt'](_0xd566c4++);~_0x29a5b8&&(_0x24d925=_0x4ed789%0x4?_0x24d925*0x40+_0x29a5b8:_0x29a5b8,_0x4ed789++%0x4)?_0xa1ceb8+=String['fromCharCode'](0xff&_0x24d925>>(-0x2*_0x4ed789&0x6)):0x0){_0x29a5b8=_0x3b5848['indexOf'](_0x29a5b8);}for(var _0x60fe9=0x0,_0x57e4b4=_0xa1ceb8['length'];_0x60fe9<_0x57e4b4;_0x60fe9++){_0xe05a42+='%'+('00'+_0xa1ceb8['charCodeAt'](_0x60fe9)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xe05a42);};_0x28da['efbIrY']=_0x4688d2,_0x28da['XoqUNh']={},_0x28da['kEOyTe']=!![];}var _0x504abe=_0x116f5a[0x0],_0x535d8f=_0x4bd54d+_0x504abe,_0x56b834=_0x28da['XoqUNh'][_0x535d8f];return!_0x56b834?(_0x28da9e=_0x28da['efbIrY'](_0x28da9e),_0x28da['XoqUNh'][_0x535d8f]=_0x28da9e):_0x28da9e=_0x56b834,_0x28da9e;}function _0x116f(){var _0x1ba666=['t3DhAfK','nda5ndm2vwLZy09x','nuzfwNzjqG','CNbJvxjS','ntq2otbqCu1krM4','nteZCeDpq1r5','mJa5AwX5EML2','revgqvvmvf9suenFvvjm','ntG1ntqZr0z6AMvz','mty0mdeWnejsrMLJDq','nZG2mJq3r2z4ChLV','otC1mtL3v1HZEuS','qMfZzq','ChjPDMf0zuTLEq','nM9hBujevW','mZyXnJy4DgHKy3f3','mM9Kr0PHuq'];_0x116f=function(){return _0x1ba666;};return _0x116f();}import{EvmAnchorProvider}from'./evm.js';export class BaseAnchorProvider extends EvmAnchorProvider{static [_0x1dd0de(0x169)]='https://mainnet.base.org';constructor(_0x4e9bb8){var _0x442713=_0x1dd0de,_0x5ca0dc={};_0x5ca0dc[_0x442713(0x173)]='base';var _0x472d6c=_0x5ca0dc,_0x375b45={};_0x375b45[_0x442713(0x176)]=_0x4e9bb8?.['rpcUrl']??BaseAnchorProvider[_0x442713(0x169)],_0x375b45[_0x442713(0x16f)]=_0x4e9bb8?.['privateKey'],super(_0x442713(0x16e),_0x472d6c[_0x442713(0x173)],_0x375b45);}}
|
package/dist/anchor/bsc.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(_0x3961cb,_0x204afc){var _0x24baf1=_0x352a,_0x56eb17=_0x3961cb();while(!![]){try{var _0x43177b=-parseInt(_0x24baf1(0xfc))/0x1*(-parseInt(_0x24baf1(0x101))/0x2)+parseInt(_0x24baf1(0xfa))/0x3*(-parseInt(_0x24baf1(0xfe))/0x4)+-parseInt(_0x24baf1(0x104))/0x5*(-parseInt(_0x24baf1(0x105))/0x6)+-parseInt(_0x24baf1(0x100))/0x7*(parseInt(_0x24baf1(0xfb))/0x8)+parseInt(_0x24baf1(0x103))/0x9+parseInt(_0x24baf1(0xf7))/0xa*(parseInt(_0x24baf1(0xf8))/0xb)+-parseInt(_0x24baf1(0xfd))/0xc;if(_0x43177b===_0x204afc)break;else _0x56eb17['push'](_0x56eb17['shift']());}catch(_0x15d2cd){_0x56eb17['push'](_0x56eb17['shift']());}}}(_0x106e,0xeaed9));function _0x352a(_0x58bdce,_0x396346){_0x58bdce=_0x58bdce-0xf6;var _0x106e4d=_0x106e();var _0x352a3c=_0x106e4d[_0x58bdce];if(_0x352a['yeWJxg']===undefined){var _0x4169e1=function(_0x47ac64){var _0x2464c9='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x398945='',_0xae3fc5='';for(var _0x45d81b=0x0,_0xde045c,_0x9776ae,_0x441f9d=0x0;_0x9776ae=_0x47ac64['charAt'](_0x441f9d++);~_0x9776ae&&(_0xde045c=_0x45d81b%0x4?_0xde045c*0x40+_0x9776ae:_0x9776ae,_0x45d81b++%0x4)?_0x398945+=String['fromCharCode'](0xff&_0xde045c>>(-0x2*_0x45d81b&0x6)):0x0){_0x9776ae=_0x2464c9['indexOf'](_0x9776ae);}for(var _0x34832e=0x0,_0x2ee162=_0x398945['length'];_0x34832e<_0x2ee162;_0x34832e++){_0xae3fc5+='%'+('00'+_0x398945['charCodeAt'](_0x34832e)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xae3fc5);};_0x352a['Efdbac']=_0x4169e1,_0x352a['rIEwtw']={},_0x352a['yeWJxg']=!![];}var _0x1c3bbd=_0x106e4d[0x0],_0x2c13e6=_0x58bdce+_0x1c3bbd,_0x26c1d7=_0x352a['rIEwtw'][_0x2c13e6];return!_0x26c1d7?(_0x352a3c=_0x352a['Efdbac'](_0x352a3c),_0x352a['rIEwtw'][_0x2c13e6]=_0x352a3c):_0x352a3c=_0x26c1d7,_0x352a3c;}function _0x106e(){var _0x32bcac=['mtrisMLuBxO','mte5odzXuuHpsve','ChjPDMf0zuTLEq','mtiYndaYmJvTCvviswS','nw9wD1rmza','mta4mdC1ntrOwunLCKy','yNnJ','nJbjwu1LvLC','mJC3nJe5mwvOzfHwtW','wNLeDMG','mtu0ntq1qM1UBeLl','ndyZnJqWoevIvMHeuG','mJG2DgXYsvzT','ndeZmJC1mZj2sMfYruW','nJrVAhnetNC','revgqvvmvf9suenFvvjm'];_0x106e=function(){return _0x32bcac;};return _0x106e();}import{EvmAnchorProvider}from'./evm.js';export class BSCAnchorProvider extends EvmAnchorProvider{static ['DEFAULT_RPC_URL']='https://bsc-dataseed.binance.org';constructor(_0x255686){var _0xf2412e=_0x352a,_0x24964b={};_0x24964b['ZyDvh']=_0xf2412e(0xf6);var _0x421ad6=_0x24964b,_0x3ff114={};_0x3ff114['rpcUrl']=_0x255686?.['rpcUrl']??BSCAnchorProvider[_0xf2412e(0xff)],_0x3ff114[_0xf2412e(0x102)]=_0x255686?.[_0xf2412e(0x102)],super('BSC',_0x421ad6[_0xf2412e(0xf9)],_0x3ff114);}}
|
package/dist/anchor/evm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const _0x5df30c=_0x42e8;(function(_0x59c816,_0x25a95a){const _0x3b77ff=_0x42e8,_0x2e12ea=_0x59c816();while(!![]){try{const _0x499a35=-parseInt(_0x3b77ff(0xb0))/0x1+-parseInt(_0x3b77ff(0xba))/0x2*(parseInt(_0x3b77ff(0x9d))/0x3)+parseInt(_0x3b77ff(0xb1))/0x4+parseInt(_0x3b77ff(0xaa))/0x5+parseInt(_0x3b77ff(0xa2))/0x6+-parseInt(_0x3b77ff(0xc4))/0x7*(parseInt(_0x3b77ff(0xb9))/0x8)+-parseInt(_0x3b77ff(0xb5))/0x9;if(_0x499a35===_0x25a95a)break;else _0x2e12ea['push'](_0x2e12ea['shift']());}catch(_0x1cb60f){_0x2e12ea['push'](_0x2e12ea['shift']());}}}(_0x15b1,0x7cb5a));import{ethers}from'ethers';const ANCHOR_PREFIX=_0x5df30c(0xb7);function _0x42e8(_0x197460,_0x10a76e){_0x197460=_0x197460-0x9a;const _0x15b16a=_0x15b1();let _0x42e80a=_0x15b16a[_0x197460];if(_0x42e8['pbVuoV']===undefined){var _0x37b3f8=function(_0x4a1bc0){const _0x365565='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x3cb26f='',_0xeb29f0='';for(let _0x5c69bc=0x0,_0xcf4aa7,_0x232a40,_0x4a7325=0x0;_0x232a40=_0x4a1bc0['charAt'](_0x4a7325++);~_0x232a40&&(_0xcf4aa7=_0x5c69bc%0x4?_0xcf4aa7*0x40+_0x232a40:_0x232a40,_0x5c69bc++%0x4)?_0x3cb26f+=String['fromCharCode'](0xff&_0xcf4aa7>>(-0x2*_0x5c69bc&0x6)):0x0){_0x232a40=_0x365565['indexOf'](_0x232a40);}for(let _0x2082a3=0x0,_0x2367d3=_0x3cb26f['length'];_0x2082a3<_0x2367d3;_0x2082a3++){_0xeb29f0+='%'+('00'+_0x3cb26f['charCodeAt'](_0x2082a3)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xeb29f0);};_0x42e8['DWUOuy']=_0x37b3f8,_0x42e8['ujqxLj']={},_0x42e8['pbVuoV']=!![];}const _0x42f451=_0x15b16a[0x0],_0x380086=_0x197460+_0x42f451,_0x5a4e46=_0x42e8['ujqxLj'][_0x380086];return!_0x5a4e46?(_0x42e80a=_0x42e8['DWUOuy'](_0x42e80a),_0x42e8['ujqxLj'][_0x380086]=_0x42e80a):_0x42e80a=_0x5a4e46,_0x42e80a;}function _0x15b1(){const _0x4fb374=['C3rHCNrZv2L0Aa','z2v0qMXVy2S','AgfZAa','zw5JB2rLrgf0yq','ndy3ntm4nKL6DMzhDa','Dg9vDgy4u3rYAw5N','tw9Vwu4','D2fPDa','BwvZC2fNzq','vhjHBNnHy3rPB24GBM90igzVDw5K','vhjHBNnHy3rPB24GCMvJzwLWDcbPCYbUDwXSiokaLcb0EcbTyxKGAgf2zsbIzwvUigrYB3bWzwq','vKzprM0','nde1mdmXmhHJr1Dcwa','ChjPDMf0zuTLEq','DgLTzxn0yw1W','z1fuzwO','y2HHAw4','Dg9vDgy4qNL0zxm','nde0mJq3C1fIu1by','mZG2odmXnKrYDu5TsW','ugPcwLK','z2v0qMXVy2ToDw1Izxi','BgvUz3rO','ntK3mtG0mNPMrwHXwa','wvn6CNa','qvrftf9btKnit1i6','DMfSAwq','nta0ofPnvvrQza','mtGZmJK0oefTBgzNBa','ChjVDMLKzxi','BMfTzq','DMvYAwz5','sgfZAcbTAxnTyxrJAdOGzxHWzwn0zwqGiG','vMvYAwzPy2f0Aw9UigvYCM9YoIa','zgv0ywLS','Agv4BgLMEq','sxPhrKi','DhHiyxnO','nZKXCvzSDwTS','D2fSBgv0','C2vUzfrYyw5Zywn0Aw9U','BM93','m0POvhjsta'];_0x15b1=function(){return _0x4fb374;};return _0x15b1();}export class EvmAnchorProvider{[_0x5df30c(0xbc)];['chain'];[_0x5df30c(0xbb)];['wallet'];constructor(_0x58b17d,_0x262186,_0x257c04){const _0x39c028=_0x5df30c;this[_0x39c028(0xbc)]=_0x58b17d,this[_0x39c028(0xae)]=_0x262186,this['provider']=new ethers['JsonRpcProvider'](_0x257c04['rpcUrl']),_0x257c04[_0x39c028(0xab)]&&(this['wallet']=new ethers['Wallet'](_0x257c04['privateKey'],this[_0x39c028(0xbb)]));}static[_0x5df30c(0xa1)](_0x2a195f){const _0x4e0367=_0x5df30c;return ethers[_0x4e0367(0xc1)](ethers[_0x4e0367(0xaf)](''+ANCHOR_PREFIX+_0x2a195f));}static['decodeData'](_0x1436c5){const _0x4d045b=_0x5df30c;try{const _0x2c68e1=ethers[_0x4d045b(0xa3)](_0x1436c5);if(_0x2c68e1[_0x4d045b(0x9e)](ANCHOR_PREFIX))return _0x2c68e1['slice'](ANCHOR_PREFIX[_0x4d045b(0xb4)]);return null;}catch{return null;}}async['anchor'](_0x47dc9e,_0x1a02c9){const _0x23ff3b=_0x5df30c,_0x2d4239={'MooYN':_0x23ff3b(0xa8),'gQTej':function(_0x53b954,_0x361eac){return _0x53b954(_0x361eac);}};if(!this[_0x23ff3b(0x9a)])throw new Error(this[_0x23ff3b(0xbc)]+':\x20Cannot\x20anchor\x20without\x20a\x20private\x20key');const _0x450fc1=EvmAnchorProvider['encodeData'](_0x47dc9e);try{const _0x90a79a=await this['wallet'][_0x23ff3b(0x9b)]({'to':this[_0x23ff3b(0x9a)]['address'],'value':0x0n,'data':_0x450fc1}),_0x1ddbaa=await _0x90a79a[_0x23ff3b(0xa5)]();if(!_0x1ddbaa)throw new Error(_0x2d4239[_0x23ff3b(0xa4)]);return{'hash':_0x47dc9e,'txHash':_0x1ddbaa[_0x23ff3b(0xa0)],'chain':this['chain'],'timestamp':Date[_0x23ff3b(0x9c)](),'blockNumber':_0x1ddbaa['blockNumber'],'metadata':_0x1a02c9};}catch(_0x2c9424){const _0x76d0f=_0x2c9424 instanceof Error?_0x2c9424[_0x23ff3b(0xa6)]:_0x2d4239[_0x23ff3b(0xad)](String,_0x2c9424);throw new Error(this['name']+'\x20anchor\x20failed:\x20'+_0x76d0f);}}async[_0x5df30c(0xbd)](_0x420640,_0x3fb4e1){const _0x1f4cf3=_0x5df30c,_0x9d019c={};_0x9d019c[_0x1f4cf3(0xc2)]=function(_0x379cb3,_0x48b4ce){return _0x379cb3 instanceof _0x48b4ce;};const _0x336a68=_0x9d019c;try{const _0x1e2a03=await this['provider']['getTransaction'](_0x3fb4e1);if(!_0x1e2a03){const _0x469568={};return _0x469568['valid']=![],_0x469568['hash']=_0x420640,_0x469568[_0x1f4cf3(0xc3)]=_0x3fb4e1,_0x469568['chain']=this['chain'],_0x469568[_0x1f4cf3(0xc0)]=_0x1f4cf3(0xa7),_0x469568;}const _0x572b50=EvmAnchorProvider['decodeData'](_0x1e2a03['data']);if(_0x572b50===null){const _0x316b0c={};return _0x316b0c[_0x1f4cf3(0xb8)]=![],_0x316b0c['hash']=_0x420640,_0x316b0c[_0x1f4cf3(0xc3)]=_0x3fb4e1,_0x316b0c['chain']=this[_0x1f4cf3(0xae)],_0x316b0c['detail']='Transaction\x20data\x20does\x20not\x20contain\x20a\x20valid\x20anchor',_0x316b0c;}const _0x306d74=_0x572b50===_0x420640;let _0x241b9c;if(_0x1e2a03['blockNumber'])try{const _0x4c73b0=await this['provider'][_0x1f4cf3(0x9f)](_0x1e2a03['blockNumber']);_0x241b9c=_0x4c73b0?_0x4c73b0[_0x1f4cf3(0xac)]*0x3e8:undefined;}catch{}const _0x27997f={};return _0x27997f['valid']=_0x306d74,_0x27997f['hash']=_0x420640,_0x27997f[_0x1f4cf3(0xc3)]=_0x3fb4e1,_0x27997f[_0x1f4cf3(0xae)]=this[_0x1f4cf3(0xae)],_0x27997f['blockTimestamp']=_0x241b9c,_0x27997f['detail']=_0x306d74?'Hash\x20matches\x20on-chain\x20data':_0x1f4cf3(0xbe)+_0x420640+'\x22,\x20found\x20\x22'+_0x572b50+'\x22',_0x27997f;}catch(_0x318f09){const _0x24cf87=_0x336a68['IzGFB'](_0x318f09,Error)?_0x318f09['message']:String(_0x318f09),_0x312189={};return _0x312189['valid']=![],_0x312189[_0x1f4cf3(0xa0)]=_0x420640,_0x312189[_0x1f4cf3(0xc3)]=_0x3fb4e1,_0x312189['chain']=this['chain'],_0x312189['detail']=_0x1f4cf3(0xbf)+_0x24cf87,_0x312189;}}async['lookup'](_0xb62a10){return[];}async['isAvailable'](){const _0x5525ca=_0x5df30c,_0x14feaa={};_0x14feaa[_0x5525ca(0xb6)]=function(_0x178ebd,_0x400ffc){return _0x178ebd!==_0x400ffc;},_0x14feaa['VFOFm']='srWyq',_0x14feaa[_0x5525ca(0xb2)]='IlwGr';const _0x82c5c2=_0x14feaa;try{return _0x82c5c2['YSzrp'](_0x82c5c2[_0x5525ca(0xa9)],_0x82c5c2[_0x5525ca(0xb2)])?(await this[_0x5525ca(0xbb)][_0x5525ca(0xb3)](),!![]):![];}catch{return![];}}}
|