@lawrenceliang-btc/atel-sdk 1.1.18 → 1.1.19

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 (2) hide show
  1. package/bin/atel.mjs +116 -102
  2. package/package.json +1 -1
package/bin/atel.mjs CHANGED
@@ -5271,108 +5271,68 @@ async function cmdResult(taskId, resultJson) {
5271
5271
 
5272
5272
  async function cmdCheck(targetDid, riskLevel, options) {
5273
5273
  const risk = riskLevel || 'low';
5274
- const chainMode = options?.chain || !!process.env.ATEL_SOLANA_RPC_URL;
5275
5274
  const policy = loadPolicy();
5276
5275
  const tp = policy.trustPolicy || DEFAULT_POLICY.trustPolicy;
5276
+ const RISK_THRESHOLDS = { low: 0, medium: 30, high: 50, critical: 75 };
5277
5277
 
5278
- console.log(JSON.stringify({ event: 'checking_trust', did: targetDid, risk, mode: chainMode ? 'chain-verified' : 'local-only' }));
5278
+ console.log(JSON.stringify({ event: 'checking_trust', did: targetDid, risk }));
5279
5279
 
5280
- // 1. Get Registry info (reference only, includes wallets)
5281
- let registryScore = null;
5282
- let agentName = null;
5283
- let peerWallets = null;
5280
+ // 1. Fetch agent profile from Platform (primary source of truth)
5281
+ let platformAgent = null;
5282
+ let platformScore = null;
5283
+ let platformReachable = true;
5284
5284
  try {
5285
- const r = await fetch(`${REGISTRY_URL}/registry/v1/agent/${encodeURIComponent(targetDid)}`, { signal: AbortSignal.timeout(5000) });
5285
+ const r = await fetch(`${ATEL_PLATFORM}/registry/v1/agent/${encodeURIComponent(targetDid)}`, { signal: AbortSignal.timeout(5000) });
5286
+ if (r.ok) {
5287
+ platformAgent = await r.json();
5288
+ platformScore = platformAgent.trustScore;
5289
+ }
5290
+ } catch {
5291
+ platformReachable = false;
5292
+ }
5293
+
5294
+ // 2. Fetch trust history from Platform
5295
+ let trustEvents = [];
5296
+ try {
5297
+ const r = await fetch(`${ATEL_PLATFORM}/registry/v1/agent/${encodeURIComponent(targetDid)}/trust-history`, { signal: AbortSignal.timeout(5000) });
5286
5298
  if (r.ok) {
5287
5299
  const d = await r.json();
5288
- registryScore = d.trustScore;
5289
- agentName = d.name;
5290
- if (d.wallets) peerWallets = d.wallets;
5300
+ trustEvents = d.events || [];
5291
5301
  }
5292
5302
  } catch {}
5293
5303
 
5294
- // 2. Local interaction history
5304
+ // 3. Local interaction history (secondary/fallback)
5295
5305
  const localHistoryFile = resolve(ATEL_DIR, 'trust-history.json');
5296
5306
  let history = {};
5297
5307
  try { history = JSON.parse(readFileSync(localHistoryFile, 'utf-8')); } catch {}
5298
5308
  const agentHistory = history[targetDid] || { tasks: 0, successes: 0, failures: 0, lastSeen: null, proofs: [] };
5309
+ const localScore = computeTrustScore(agentHistory);
5299
5310
 
5300
- // 3. Chain-verified mode: query all three chains by wallet address
5301
- let chainVerification = null;
5302
- if (chainMode) {
5303
- const chainResults = { solana: null, base: null, bsc: null, totalRecords: 0, matchingDid: 0 };
5304
-
5305
- // 3a. Verify unverified local proofs on-chain
5306
- const unverifiedProofs = agentHistory.proofs.filter(p => !p.verified && p.anchor_tx);
5307
- if (unverifiedProofs.length > 0) {
5308
- console.log(JSON.stringify({ event: 'verifying_local_proofs', count: unverifiedProofs.length }));
5309
- const result = await verifyAnchorTxList(unverifiedProofs, targetDid);
5310
- for (const vp of result.proofs) {
5311
- const existing = agentHistory.proofs.find(p => p.anchor_tx === vp.anchor_tx);
5312
- if (existing) existing.verified = true;
5313
- }
5314
- history[targetDid] = agentHistory;
5315
- try { writeFileSync(localHistoryFile, JSON.stringify(history, null, 2)); } catch {}
5316
- }
5317
-
5318
- // 3b. Query peer's wallet addresses on all three chains
5319
- if (peerWallets) {
5320
- console.log(JSON.stringify({ event: 'querying_chain_history', wallets: peerWallets }));
5321
-
5322
- // Solana
5323
- if (peerWallets.solana) {
5324
- try {
5325
- const rpcUrl = process.env.ATEL_SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com';
5326
- const provider = new SolanaAnchorProvider({ rpcUrl });
5327
- const records = await provider.queryByWallet(peerWallets.solana, { limit: 100, filterDid: targetDid });
5328
- chainResults.solana = { wallet: peerWallets.solana, records: records.length, asExecutor: records.filter(r => r.executorDid === targetDid).length, asRequester: records.filter(r => r.requesterDid === targetDid).length };
5329
- chainResults.totalRecords += records.length;
5330
- chainResults.matchingDid += records.length;
5331
- } catch (e) { chainResults.solana = { error: e.message }; }
5332
- }
5333
-
5334
- // Base
5335
- if (peerWallets.base) {
5336
- try {
5337
- const { BaseAnchorProvider } = await import('@lawrenceliang-btc/atel-sdk');
5338
- const baseRpc = process.env.ATEL_BASE_RPC_URL || 'https://mainnet.base.org';
5339
- const provider = new BaseAnchorProvider({ rpcUrl: baseRpc });
5340
- const explorerApi = process.env.ATEL_BASE_EXPLORER_API || 'https://api.basescan.org/api';
5341
- const apiKey = process.env.ATEL_BASE_EXPLORER_KEY;
5342
- const records = await provider.queryByWallet(peerWallets.base, explorerApi, apiKey, { limit: 100, filterDid: targetDid });
5343
- chainResults.base = { wallet: peerWallets.base, records: records.length, asExecutor: records.filter(r => r.executorDid === targetDid).length, asRequester: records.filter(r => r.requesterDid === targetDid).length };
5344
- chainResults.totalRecords += records.length;
5345
- chainResults.matchingDid += records.length;
5346
- } catch (e) { chainResults.base = { error: e.message }; }
5347
- }
5348
-
5349
- // BSC
5350
- if (peerWallets.bsc) {
5351
- try {
5352
- const { BSCAnchorProvider } = await import('@lawrenceliang-btc/atel-sdk');
5353
- const bscRpc = process.env.ATEL_BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
5354
- const provider = new BSCAnchorProvider({ rpcUrl: bscRpc });
5355
- const explorerApi = process.env.ATEL_BSC_EXPLORER_API || 'https://api.bscscan.com/api';
5356
- const apiKey = process.env.ATEL_BSC_EXPLORER_KEY;
5357
- const records = await provider.queryByWallet(peerWallets.bsc, explorerApi, apiKey, { limit: 100, filterDid: targetDid });
5358
- chainResults.bsc = { wallet: peerWallets.bsc, records: records.length, asExecutor: records.filter(r => r.executorDid === targetDid).length, asRequester: records.filter(r => r.requesterDid === targetDid).length };
5359
- chainResults.totalRecords += records.length;
5360
- chainResults.matchingDid += records.length;
5361
- } catch (e) { chainResults.bsc = { error: e.message }; }
5311
+ // 4. Local TrustGraph info (supplementary)
5312
+ let graphInfo = null;
5313
+ try {
5314
+ const saved = JSON.parse(readFileSync(resolve(ATEL_DIR, 'trust-graph.json'), 'utf-8'));
5315
+ if (saved.interactions) {
5316
+ const tg = new TrustGraph();
5317
+ for (const i of saved.interactions) tg.recordInteraction(i);
5318
+ const directConns = saved.interactions.filter(
5319
+ i => i.from === targetDid || i.to === targetDid
5320
+ );
5321
+ if (directConns.length > 0) {
5322
+ const stats = tg.getStats();
5323
+ graphInfo = { directConnections: directConns.length, stats };
5362
5324
  }
5363
5325
  }
5326
+ } catch {}
5364
5327
 
5365
- chainVerification = chainResults;
5366
- }
5367
-
5368
- // 4. Compute unified trust score and level
5369
- const computedScore = computeTrustScore(agentHistory);
5370
- const trustLevel = computeTrustLevel(computedScore);
5328
+ // 5. Determine effective score: Platform is primary, local is fallback
5329
+ const effectiveScore = platformScore !== null ? platformScore : localScore;
5330
+ const scoreSource = platformScore !== null ? 'platform' : 'local';
5331
+ const trustLevel = computeTrustLevel(effectiveScore);
5371
5332
 
5372
- // 5. Apply trust policy
5373
- const threshold = tp.riskThresholds?.[risk] ?? 0;
5374
- const effectiveScore = computedScore > 0 ? computedScore : (registryScore || 0);
5375
- const isNewAgent = agentHistory.tasks === 0;
5333
+ // 6. Apply trust policy (allow/deny decision)
5334
+ const threshold = RISK_THRESHOLDS[risk] ?? (tp.riskThresholds?.[risk] ?? 0);
5335
+ const isNewAgent = platformAgent === null && agentHistory.tasks === 0;
5376
5336
  let decision = 'allow';
5377
5337
  let reason = '';
5378
5338
 
@@ -5391,28 +5351,82 @@ async function cmdCheck(targetDid, riskLevel, options) {
5391
5351
  reason = `Score ${effectiveScore} meets threshold ${threshold} for ${risk} risk`;
5392
5352
  }
5393
5353
 
5354
+ // 7. Build human-readable output
5355
+ const lines = [];
5356
+ lines.push(`Trust Check: ${targetDid}`);
5357
+ if (platformAgent?.name) lines.push(` Name: ${platformAgent.name}`);
5358
+ lines.push(` Platform Score: ${effectiveScore} / 100${scoreSource === 'local' ? ' (fallback: local)' : ''}`);
5359
+ lines.push(` Decision: ${decision} (threshold: ${threshold} for ${risk} risk)`);
5360
+ if (reason) lines.push(` Reason: ${reason}`);
5361
+
5362
+ // Recent events from Platform
5363
+ if (trustEvents.length > 0) {
5364
+ lines.push(` Recent Events:`);
5365
+ for (const ev of trustEvents.slice(0, 10)) {
5366
+ const delta = ev.scoreDelta >= 0 ? `+${ev.scoreDelta}` : `${ev.scoreDelta}`;
5367
+ const date = ev.createdAt ? ev.createdAt.split('T')[0] : '';
5368
+ const ref = ev.referenceId || '';
5369
+ lines.push(` ${delta.padEnd(8)} ${ev.eventType.padEnd(22)} ${ref.padEnd(16)} ${date}`);
5370
+ }
5371
+ if (trustEvents.length > 10) lines.push(` ... and ${trustEvents.length - 10} more`);
5372
+ }
5373
+
5374
+ // Stats from Platform
5375
+ if (platformAgent?.stats) {
5376
+ const s = platformAgent.stats;
5377
+ const successPct = s.successRate != null ? `${Math.round(s.successRate * 100)}%` : 'n/a';
5378
+ lines.push(` Stats: ${s.totalTasks} tasks, ${successPct} success${s.avgRating ? `, avg rating: ${s.avgRating.toFixed(1)}` : ''}`);
5379
+ } else if (agentHistory.tasks > 0) {
5380
+ const successPct = agentHistory.tasks > 0 ? `${Math.round((agentHistory.successes / agentHistory.tasks) * 100)}%` : 'n/a';
5381
+ lines.push(` Stats: ${agentHistory.tasks} tasks, ${successPct} success (local)`);
5382
+ }
5383
+
5384
+ // Verified & Certification from Platform
5385
+ if (platformAgent) {
5386
+ lines.push(` Verified: ${platformAgent.verified || false}`);
5387
+ if (platformAgent.certification) {
5388
+ lines.push(` Certification: ${platformAgent.certification.level} (since ${platformAgent.certification.since})`);
5389
+ }
5390
+ if (platformAgent.boost?.active) {
5391
+ lines.push(` Boost: ${platformAgent.boost.tier} (active)`);
5392
+ }
5393
+ }
5394
+
5395
+ // Local TrustGraph supplementary info
5396
+ if (graphInfo) {
5397
+ lines.push(` Local Graph: ${graphInfo.directConnections} direct connection${graphInfo.directConnections !== 1 ? 's' : ''}`);
5398
+ }
5399
+
5400
+ // Fallback warning
5401
+ if (!platformReachable) {
5402
+ lines.push(` Warning: Platform unreachable, using local score as fallback`);
5403
+ }
5404
+
5405
+ // Print human-readable output
5406
+ console.log(lines.join('\n'));
5407
+
5408
+ // Also emit structured JSON for machine consumption
5394
5409
  const output = {
5395
5410
  did: targetDid,
5396
- name: agentName,
5397
- mode: chainMode ? 'chain-verified' : 'local-only',
5398
- trust: {
5399
- computed_score: computedScore,
5400
- registry_score: registryScore,
5401
- effective_score: effectiveScore,
5402
- level: trustLevel.level,
5403
- level_name: trustLevel.name,
5404
- max_risk: trustLevel.maxRisk,
5405
- total_tasks: agentHistory.tasks,
5406
- successes: agentHistory.successes,
5407
- failures: agentHistory.failures,
5408
- verified_proofs: agentHistory.proofs.filter(p => p.verified).length,
5409
- total_proofs: agentHistory.proofs.length,
5410
- },
5411
- policy: { risk, threshold, decision, reason },
5411
+ name: platformAgent?.name || null,
5412
+ score: effectiveScore,
5413
+ scoreSource,
5414
+ level: trustLevel.level,
5415
+ levelName: trustLevel.name,
5416
+ decision,
5417
+ risk,
5418
+ threshold,
5419
+ reason,
5420
+ verified: platformAgent?.verified || false,
5421
+ certification: platformAgent?.certification || null,
5422
+ stats: platformAgent?.stats || null,
5423
+ recentEvents: trustEvents.slice(0, 10),
5424
+ localGraph: graphInfo,
5425
+ platformReachable,
5412
5426
  };
5413
- if (chainVerification) output.chain_verification = chainVerification;
5414
- if (!chainMode) output.note = 'Local-only mode: score based on direct interaction history only. Set ATEL_SOLANA_RPC_URL or use --chain for on-chain verification.';
5415
-
5427
+ if (localScore > 0 && scoreSource === 'platform') {
5428
+ output.localScore = localScore;
5429
+ }
5416
5430
  console.log(JSON.stringify(output, null, 2));
5417
5431
  }
5418
5432
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lawrenceliang-btc/atel-sdk",
3
- "version": "1.1.18",
3
+ "version": "1.1.19",
4
4
  "description": "ATEL Protocol SDK - Agent Trust & Exchange Layer",
5
5
  "repository": {
6
6
  "type": "git",