@highway1/core 0.1.43 → 0.1.45
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 +68 -40
- package/dist/index.js.map +1 -1
- package/package.json +18 -4
- package/src/discovery/agent-card-encoder.ts +119 -0
- package/src/discovery/agent-card-schema.ts +87 -0
- package/src/discovery/agent-card-types.ts +99 -0
- package/src/discovery/agent-card.ts +190 -0
- package/src/discovery/bootstrap.ts +63 -0
- package/src/discovery/capability-matcher.ts +167 -0
- package/src/discovery/dht.ts +310 -0
- package/src/discovery/index.ts +3 -0
- package/src/discovery/search-index.ts +247 -0
- package/src/discovery/semantic-search.ts +218 -0
- package/src/identity/did.ts +48 -0
- package/src/identity/document.ts +77 -0
- package/src/identity/index.ts +4 -0
- package/src/identity/keys.ts +79 -0
- package/src/identity/signer.ts +55 -0
- package/src/index.ts +33 -0
- package/src/messaging/codec.ts +47 -0
- package/src/messaging/envelope.ts +107 -0
- package/src/messaging/index.ts +3 -0
- package/src/messaging/router.ts +384 -0
- package/src/transport/connection.ts +77 -0
- package/src/transport/index.ts +2 -0
- package/src/transport/node.ts +152 -0
- package/src/trust/endorsement.ts +167 -0
- package/src/trust/index.ts +194 -0
- package/src/trust/interaction-history.ts +155 -0
- package/src/trust/sybil-defense.ts +232 -0
- package/src/trust/trust-score.ts +136 -0
- package/src/utils/errors.ts +38 -0
- package/src/utils/logger.ts +48 -0
package/dist/index.js
CHANGED
|
@@ -257,8 +257,8 @@ async function createNode(config) {
|
|
|
257
257
|
// Optimize for small networks: reduce replication factor and query timeout
|
|
258
258
|
kBucketSize: 20,
|
|
259
259
|
// Default K=20, keep for compatibility
|
|
260
|
-
querySelfInterval:
|
|
261
|
-
// Self-query every
|
|
260
|
+
querySelfInterval: 3e4,
|
|
261
|
+
// Self-query every 30 seconds (libp2p default)
|
|
262
262
|
// Allow queries to complete faster in small networks
|
|
263
263
|
allowQueryWithZeroPeers: true
|
|
264
264
|
});
|
|
@@ -1032,6 +1032,8 @@ function createSemanticSearch(dht) {
|
|
|
1032
1032
|
|
|
1033
1033
|
// src/discovery/dht.ts
|
|
1034
1034
|
var logger4 = createLogger("dht");
|
|
1035
|
+
var peerCache = /* @__PURE__ */ new Map();
|
|
1036
|
+
var CACHE_TTL = 5 * 60 * 1e3;
|
|
1035
1037
|
function extractValue(event) {
|
|
1036
1038
|
if (event.name === "VALUE" && event.value) return event.value;
|
|
1037
1039
|
if (event.name === "PEER_RESPONSE" && event.value) return event.value;
|
|
@@ -1094,7 +1096,7 @@ function createDHTOperations(libp2p) {
|
|
|
1094
1096
|
}
|
|
1095
1097
|
const caps = (card.capabilities ?? []).flatMap((c) => {
|
|
1096
1098
|
if (typeof c === "string") return [c];
|
|
1097
|
-
return [c.name, c.id].filter(
|
|
1099
|
+
return [c.name, c.id].filter((v) => typeof v === "string" && v.length > 0);
|
|
1098
1100
|
});
|
|
1099
1101
|
caps.push("__all__");
|
|
1100
1102
|
const importantCaps = ["__all__"];
|
|
@@ -1222,6 +1224,11 @@ function createDHTOperations(libp2p) {
|
|
|
1222
1224
|
},
|
|
1223
1225
|
resolveDID: async (did) => {
|
|
1224
1226
|
try {
|
|
1227
|
+
const cached = peerCache.get(did);
|
|
1228
|
+
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
|
|
1229
|
+
logger4.debug("Using cached peer info", { did });
|
|
1230
|
+
return { peerId: cached.peerId, multiaddrs: cached.multiaddrs };
|
|
1231
|
+
}
|
|
1225
1232
|
const dht = libp2p.services?.dht;
|
|
1226
1233
|
if (!dht) throw new DiscoveryError("DHT service not available");
|
|
1227
1234
|
const key = fromString(`/clawiverse/agent/${did}`);
|
|
@@ -1231,7 +1238,13 @@ function createDHTOperations(libp2p) {
|
|
|
1231
1238
|
const card = decodeFromCBOR(raw);
|
|
1232
1239
|
if (card.peerId) {
|
|
1233
1240
|
logger4.debug("Resolved DID to peer", { did, peerId: card.peerId });
|
|
1234
|
-
|
|
1241
|
+
const result = { peerId: card.peerId, multiaddrs: card.endpoints || [] };
|
|
1242
|
+
peerCache.set(did, {
|
|
1243
|
+
peerId: result.peerId,
|
|
1244
|
+
multiaddrs: result.multiaddrs,
|
|
1245
|
+
timestamp: Date.now()
|
|
1246
|
+
});
|
|
1247
|
+
return result;
|
|
1235
1248
|
}
|
|
1236
1249
|
logger4.warn("Agent Card found but has no peerId", { did });
|
|
1237
1250
|
return null;
|
|
@@ -1323,6 +1336,18 @@ function decodeMessageJSON(json) {
|
|
|
1323
1336
|
}
|
|
1324
1337
|
}
|
|
1325
1338
|
var logger5 = createLogger("router");
|
|
1339
|
+
function concatUint8Arrays(arrays) {
|
|
1340
|
+
if (arrays.length === 0) return new Uint8Array(0);
|
|
1341
|
+
if (arrays.length === 1) return arrays[0];
|
|
1342
|
+
const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
|
|
1343
|
+
const result = new Uint8Array(totalLength);
|
|
1344
|
+
let offset = 0;
|
|
1345
|
+
for (const arr of arrays) {
|
|
1346
|
+
result.set(arr, offset);
|
|
1347
|
+
offset += arr.length;
|
|
1348
|
+
}
|
|
1349
|
+
return result;
|
|
1350
|
+
}
|
|
1326
1351
|
function createMessageRouter(libp2p, verifyFn, dht, relayPeers) {
|
|
1327
1352
|
const handlers = /* @__PURE__ */ new Map();
|
|
1328
1353
|
let catchAllHandler;
|
|
@@ -1373,16 +1398,25 @@ function createMessageRouter(libp2p, verifyFn, dht, relayPeers) {
|
|
|
1373
1398
|
multiaddrs: targetMultiaddrs
|
|
1374
1399
|
});
|
|
1375
1400
|
let stream;
|
|
1401
|
+
const DIAL_TIMEOUT = 3e3;
|
|
1376
1402
|
const relayMultiaddrs = targetMultiaddrs.filter((a) => a.includes("/p2p-circuit/"));
|
|
1377
1403
|
const directMultiaddrs = targetMultiaddrs.filter((a) => !a.includes("/p2p-circuit/"));
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1404
|
+
if (directMultiaddrs.length > 0) {
|
|
1405
|
+
const directDialPromises = directMultiaddrs.map(async (addr) => {
|
|
1406
|
+
try {
|
|
1407
|
+
const conn = await libp2p.dial(multiaddr(addr), {
|
|
1408
|
+
signal: AbortSignal.timeout(DIAL_TIMEOUT)
|
|
1409
|
+
});
|
|
1410
|
+
const s = await conn.newStream(PROTOCOL_PREFIX, { runOnLimitedConnection: true });
|
|
1411
|
+
logger5.info("Direct dial succeeded", { addr });
|
|
1412
|
+
return s;
|
|
1413
|
+
} catch {
|
|
1414
|
+
return null;
|
|
1415
|
+
}
|
|
1416
|
+
});
|
|
1417
|
+
stream = await Promise.race(
|
|
1418
|
+
directDialPromises.map((p) => p.then((s) => s || Promise.reject()))
|
|
1419
|
+
).catch(() => void 0);
|
|
1386
1420
|
}
|
|
1387
1421
|
let lastError;
|
|
1388
1422
|
if (!stream) {
|
|
@@ -1391,17 +1425,25 @@ function createMessageRouter(libp2p, verifyFn, dht, relayPeers) {
|
|
|
1391
1425
|
...(relayPeers ?? []).map((r) => buildCircuitRelayAddr(r, targetPeerIdStr))
|
|
1392
1426
|
];
|
|
1393
1427
|
const uniqueRelayAddrs = [...new Set(allRelayAddrs)];
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1428
|
+
if (uniqueRelayAddrs.length > 0) {
|
|
1429
|
+
const relayDialPromises = uniqueRelayAddrs.map(async (addr) => {
|
|
1430
|
+
try {
|
|
1431
|
+
const conn = await libp2p.dial(multiaddr(addr), {
|
|
1432
|
+
signal: AbortSignal.timeout(DIAL_TIMEOUT)
|
|
1433
|
+
});
|
|
1434
|
+
logger5.info("Relay connection established", { addr });
|
|
1435
|
+
const s = await conn.newStream(PROTOCOL_PREFIX, { runOnLimitedConnection: true });
|
|
1436
|
+
logger5.info("Relay stream opened", { addr });
|
|
1437
|
+
return s;
|
|
1438
|
+
} catch (relayErr) {
|
|
1439
|
+
logger5.warn("Relay dial failed", { addr, error: relayErr.message });
|
|
1440
|
+
lastError = relayErr;
|
|
1441
|
+
return null;
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
stream = await Promise.race(
|
|
1445
|
+
relayDialPromises.map((p) => p.then((s) => s || Promise.reject()))
|
|
1446
|
+
).catch(() => void 0);
|
|
1405
1447
|
}
|
|
1406
1448
|
}
|
|
1407
1449
|
if (!stream && dht && "queryRelayPeers" in dht) {
|
|
@@ -1437,21 +1479,14 @@ function createMessageRouter(libp2p, verifyFn, dht, relayPeers) {
|
|
|
1437
1479
|
if (envelope.type === "request") {
|
|
1438
1480
|
logger5.debug("Waiting for response to request", { id: envelope.id });
|
|
1439
1481
|
try {
|
|
1440
|
-
const RESPONSE_TIMEOUT =
|
|
1482
|
+
const RESPONSE_TIMEOUT = 5e3;
|
|
1441
1483
|
const responsePromise = (async () => {
|
|
1442
1484
|
const responseChunks = [];
|
|
1443
1485
|
for await (const chunk of stream.source) {
|
|
1444
1486
|
responseChunks.push(chunk.subarray());
|
|
1445
1487
|
}
|
|
1446
1488
|
if (responseChunks.length > 0) {
|
|
1447
|
-
const responseData =
|
|
1448
|
-
responseChunks.reduce((acc, chunk) => acc + chunk.length, 0)
|
|
1449
|
-
);
|
|
1450
|
-
let offset = 0;
|
|
1451
|
-
for (const chunk of responseChunks) {
|
|
1452
|
-
responseData.set(chunk, offset);
|
|
1453
|
-
offset += chunk.length;
|
|
1454
|
-
}
|
|
1489
|
+
const responseData = concatUint8Arrays(responseChunks);
|
|
1455
1490
|
const responseEnvelope = decodeMessage(responseData);
|
|
1456
1491
|
logger5.info("Received response", {
|
|
1457
1492
|
id: responseEnvelope.id,
|
|
@@ -1509,14 +1544,7 @@ async function handleIncomingStream(stream, handlers, catchAllHandler, verifyFn)
|
|
|
1509
1544
|
for await (const chunk of stream.source) {
|
|
1510
1545
|
chunks.push(chunk.subarray());
|
|
1511
1546
|
}
|
|
1512
|
-
const data =
|
|
1513
|
-
chunks.reduce((acc, chunk) => acc + chunk.length, 0)
|
|
1514
|
-
);
|
|
1515
|
-
let offset = 0;
|
|
1516
|
-
for (const chunk of chunks) {
|
|
1517
|
-
data.set(chunk, offset);
|
|
1518
|
-
offset += chunk.length;
|
|
1519
|
-
}
|
|
1547
|
+
const data = concatUint8Arrays(chunks);
|
|
1520
1548
|
const envelope = decodeMessage(data);
|
|
1521
1549
|
if (!validateEnvelope(envelope)) {
|
|
1522
1550
|
logger5.warn("Received invalid message envelope");
|