@agentvault/agentvault 0.19.58 → 0.19.60
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/_cp.d.ts +10 -0
- package/dist/_cp.d.ts.map +1 -0
- package/dist/account-config.d.ts +20 -0
- package/dist/account-config.d.ts.map +1 -0
- package/dist/channel.d.ts +391 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1218 -473
- package/dist/cli.js.map +3 -3
- package/dist/create-agent.d.ts +28 -0
- package/dist/create-agent.d.ts.map +1 -0
- package/dist/credential-store.d.ts +62 -0
- package/dist/credential-store.d.ts.map +1 -0
- package/dist/crypto-helpers.d.ts +2 -0
- package/dist/crypto-helpers.d.ts.map +1 -0
- package/dist/doctor.d.ts +41 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/fetch-interceptor.d.ts +32 -0
- package/dist/fetch-interceptor.d.ts.map +1 -0
- package/dist/gateway-send.d.ts +98 -0
- package/dist/gateway-send.d.ts.map +1 -0
- package/dist/http-handlers.d.ts +53 -0
- package/dist/http-handlers.d.ts.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1156 -473
- package/dist/index.js.map +3 -3
- package/dist/mcp-handlers.d.ts +26 -0
- package/dist/mcp-handlers.d.ts.map +1 -0
- package/dist/mcp-proxy-helpers.d.ts +9 -0
- package/dist/mcp-proxy-helpers.d.ts.map +1 -0
- package/dist/mcp-server.d.ts +91 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mls-state.d.ts +16 -0
- package/dist/mls-state.d.ts.map +1 -0
- package/dist/openclaw-compat.d.ts +33 -0
- package/dist/openclaw-compat.d.ts.map +1 -0
- package/dist/openclaw-entry.d.ts +32 -0
- package/dist/openclaw-entry.d.ts.map +1 -0
- package/dist/openclaw-plugin.d.ts +102 -0
- package/dist/openclaw-plugin.d.ts.map +1 -0
- package/dist/openclaw-types.d.ts +186 -0
- package/dist/openclaw-types.d.ts.map +1 -0
- package/dist/policy-enforcer.d.ts +78 -0
- package/dist/policy-enforcer.d.ts.map +1 -0
- package/dist/setup.d.ts +27 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/skill-invoker.d.ts +30 -0
- package/dist/skill-invoker.d.ts.map +1 -0
- package/dist/skill-manifest.d.ts +30 -0
- package/dist/skill-manifest.d.ts.map +1 -0
- package/dist/skill-telemetry.d.ts +36 -0
- package/dist/skill-telemetry.d.ts.map +1 -0
- package/dist/skills-publish.d.ts +8 -0
- package/dist/skills-publish.d.ts.map +1 -0
- package/dist/state.d.ts +32 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/transport.d.ts +24 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/types.d.ts +421 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/workspace-handlers.d.ts +62 -0
- package/dist/workspace-handlers.d.ts.map +1 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44659,6 +44659,13 @@ function computeFingerprint(publicKey) {
|
|
|
44659
44659
|
function createProofOfPossession(privateKey, publicKey) {
|
|
44660
44660
|
return libsodium_wrappers_default.crypto_sign_detached(publicKey, privateKey);
|
|
44661
44661
|
}
|
|
44662
|
+
function verifyProofOfPossession(proof, publicKey) {
|
|
44663
|
+
try {
|
|
44664
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(proof, publicKey, publicKey);
|
|
44665
|
+
} catch {
|
|
44666
|
+
return false;
|
|
44667
|
+
}
|
|
44668
|
+
}
|
|
44662
44669
|
var init_keys = __esm({
|
|
44663
44670
|
async "../crypto/dist/keys.js"() {
|
|
44664
44671
|
"use strict";
|
|
@@ -45127,6 +45134,74 @@ function jsonCanonical(value) {
|
|
|
45127
45134
|
}
|
|
45128
45135
|
return JSON.stringify(value);
|
|
45129
45136
|
}
|
|
45137
|
+
function base58Encode(bytes) {
|
|
45138
|
+
let zeros = 0;
|
|
45139
|
+
for (const b2 of bytes) {
|
|
45140
|
+
if (b2 === 0)
|
|
45141
|
+
zeros++;
|
|
45142
|
+
else
|
|
45143
|
+
break;
|
|
45144
|
+
}
|
|
45145
|
+
let num = BigInt(0);
|
|
45146
|
+
for (const b2 of bytes) {
|
|
45147
|
+
num = num * 256n + BigInt(b2);
|
|
45148
|
+
}
|
|
45149
|
+
let result = "";
|
|
45150
|
+
while (num > 0n) {
|
|
45151
|
+
const remainder = Number(num % 58n);
|
|
45152
|
+
num = num / 58n;
|
|
45153
|
+
result = BASE58_ALPHABET[remainder] + result;
|
|
45154
|
+
}
|
|
45155
|
+
return "1".repeat(zeros) + result;
|
|
45156
|
+
}
|
|
45157
|
+
function base58Decode(str) {
|
|
45158
|
+
let zeros = 0;
|
|
45159
|
+
for (const c2 of str) {
|
|
45160
|
+
if (c2 === "1")
|
|
45161
|
+
zeros++;
|
|
45162
|
+
else
|
|
45163
|
+
break;
|
|
45164
|
+
}
|
|
45165
|
+
let num = BigInt(0);
|
|
45166
|
+
for (const c2 of str.slice(zeros)) {
|
|
45167
|
+
const idx = BASE58_ALPHABET.indexOf(c2);
|
|
45168
|
+
if (idx === -1)
|
|
45169
|
+
throw new Error(`Invalid base58 character: ${c2}`);
|
|
45170
|
+
num = num * 58n + BigInt(idx);
|
|
45171
|
+
}
|
|
45172
|
+
const hex3 = num === 0n ? "" : num.toString(16).padStart(2, "0");
|
|
45173
|
+
const paddedHex = hex3.length % 2 ? "0" + hex3 : hex3;
|
|
45174
|
+
const dataBytes = new Uint8Array((paddedHex.match(/.{2}/g) ?? []).map((b2) => parseInt(b2, 16)));
|
|
45175
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
45176
|
+
result.set(dataBytes, zeros);
|
|
45177
|
+
return result;
|
|
45178
|
+
}
|
|
45179
|
+
function publicKeyToMultibase(publicKey) {
|
|
45180
|
+
const prefixed = new Uint8Array(2 + publicKey.length);
|
|
45181
|
+
prefixed[0] = 237;
|
|
45182
|
+
prefixed[1] = 1;
|
|
45183
|
+
prefixed.set(publicKey, 2);
|
|
45184
|
+
return "z" + base58Encode(prefixed);
|
|
45185
|
+
}
|
|
45186
|
+
function multibaseToPublicKey(multibase) {
|
|
45187
|
+
if (!multibase.startsWith("z")) {
|
|
45188
|
+
throw new Error("Multibase string must start with 'z' (base58btc)");
|
|
45189
|
+
}
|
|
45190
|
+
const decoded = base58Decode(multibase.slice(1));
|
|
45191
|
+
if (decoded.length < 2 || decoded[0] !== 237 || decoded[1] !== 1) {
|
|
45192
|
+
throw new Error("Invalid Ed25519 multicodec prefix");
|
|
45193
|
+
}
|
|
45194
|
+
return decoded.slice(2);
|
|
45195
|
+
}
|
|
45196
|
+
async function signDocument(document, privateKey) {
|
|
45197
|
+
await libsodium_wrappers_default.ready;
|
|
45198
|
+
const canonical = canonicalize(document);
|
|
45199
|
+
const domainPrefix = libsodium_wrappers_default.from_string(DOMAIN_DID_DOCUMENT);
|
|
45200
|
+
const message = new Uint8Array(domainPrefix.length + canonical.length);
|
|
45201
|
+
message.set(domainPrefix);
|
|
45202
|
+
message.set(canonical, domainPrefix.length);
|
|
45203
|
+
return libsodium_wrappers_default.crypto_sign_detached(message, privateKey);
|
|
45204
|
+
}
|
|
45130
45205
|
async function verifyDocumentSignature(document, signature, publicKey) {
|
|
45131
45206
|
await libsodium_wrappers_default.ready;
|
|
45132
45207
|
const canonical = canonicalize(document);
|
|
@@ -45140,12 +45215,61 @@ async function verifyDocumentSignature(document, signature, publicKey) {
|
|
|
45140
45215
|
return false;
|
|
45141
45216
|
}
|
|
45142
45217
|
}
|
|
45143
|
-
|
|
45218
|
+
function buildDidDocument(params) {
|
|
45219
|
+
const { hubAddress, ownerPublicKey, agentPublicKey, serviceEndpoint, profileEndpoint } = params;
|
|
45220
|
+
const didId = `did:hub:${hubAddress}`;
|
|
45221
|
+
const ownerMultibase = publicKeyToMultibase(ownerPublicKey);
|
|
45222
|
+
const agentMultibase = publicKeyToMultibase(agentPublicKey);
|
|
45223
|
+
const controllerDid = `did:key:${ownerMultibase}`;
|
|
45224
|
+
const now = params.created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45225
|
+
return {
|
|
45226
|
+
"@context": [
|
|
45227
|
+
"https://www.w3.org/ns/did/v1",
|
|
45228
|
+
"https://w3id.org/security/suites/ed25519-2020/v1"
|
|
45229
|
+
],
|
|
45230
|
+
id: didId,
|
|
45231
|
+
controller: controllerDid,
|
|
45232
|
+
verificationMethod: [
|
|
45233
|
+
{
|
|
45234
|
+
id: `${didId}#owner-key`,
|
|
45235
|
+
type: "Ed25519VerificationKey2020",
|
|
45236
|
+
controller: didId,
|
|
45237
|
+
publicKeyMultibase: ownerMultibase
|
|
45238
|
+
},
|
|
45239
|
+
{
|
|
45240
|
+
id: `${didId}#agent-key`,
|
|
45241
|
+
type: "Ed25519VerificationKey2020",
|
|
45242
|
+
controller: didId,
|
|
45243
|
+
publicKeyMultibase: agentMultibase
|
|
45244
|
+
}
|
|
45245
|
+
],
|
|
45246
|
+
authentication: [`${didId}#owner-key`],
|
|
45247
|
+
assertionMethod: [`${didId}#owner-key`, `${didId}#agent-key`],
|
|
45248
|
+
service: [
|
|
45249
|
+
{
|
|
45250
|
+
id: `${didId}#messaging`,
|
|
45251
|
+
type: "AgentVaultSecureChannel",
|
|
45252
|
+
serviceEndpoint
|
|
45253
|
+
},
|
|
45254
|
+
{
|
|
45255
|
+
id: `${didId}#profile`,
|
|
45256
|
+
type: "AgentVaultProfile",
|
|
45257
|
+
serviceEndpoint: profileEndpoint
|
|
45258
|
+
}
|
|
45259
|
+
],
|
|
45260
|
+
created: now,
|
|
45261
|
+
updated: now
|
|
45262
|
+
};
|
|
45263
|
+
}
|
|
45264
|
+
var DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET;
|
|
45144
45265
|
var init_did = __esm({
|
|
45145
45266
|
async "../crypto/dist/did.js"() {
|
|
45146
45267
|
"use strict";
|
|
45147
45268
|
await init_libsodium_wrappers();
|
|
45148
45269
|
DOMAIN_DID_DOCUMENT = "DID-DOCUMENT:";
|
|
45270
|
+
DOMAIN_TRANSFER_INTENT = "TRANSFER-INTENT:";
|
|
45271
|
+
DOMAIN_TRANSFER_ACCEPT = "TRANSFER-ACCEPT:";
|
|
45272
|
+
BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
45149
45273
|
}
|
|
45150
45274
|
});
|
|
45151
45275
|
|
|
@@ -45428,25 +45552,373 @@ var init_scan_engine = __esm({
|
|
|
45428
45552
|
});
|
|
45429
45553
|
|
|
45430
45554
|
// ../crypto/dist/merkle.js
|
|
45555
|
+
function jcsCanonical(value) {
|
|
45556
|
+
if (value === void 0)
|
|
45557
|
+
return void 0;
|
|
45558
|
+
if (value === null)
|
|
45559
|
+
return "null";
|
|
45560
|
+
if (typeof value === "boolean" || typeof value === "number")
|
|
45561
|
+
return JSON.stringify(value);
|
|
45562
|
+
if (typeof value === "string")
|
|
45563
|
+
return JSON.stringify(value);
|
|
45564
|
+
if (Array.isArray(value)) {
|
|
45565
|
+
return "[" + value.map(jcsCanonical).join(",") + "]";
|
|
45566
|
+
}
|
|
45567
|
+
if (typeof value === "object") {
|
|
45568
|
+
const keys = Object.keys(value).sort();
|
|
45569
|
+
const entries = keys.map((k2) => {
|
|
45570
|
+
const v2 = jcsCanonical(value[k2]);
|
|
45571
|
+
if (v2 === void 0)
|
|
45572
|
+
return void 0;
|
|
45573
|
+
return JSON.stringify(k2) + ":" + v2;
|
|
45574
|
+
}).filter((entry) => entry !== void 0);
|
|
45575
|
+
return "{" + entries.join(",") + "}";
|
|
45576
|
+
}
|
|
45577
|
+
return JSON.stringify(value);
|
|
45578
|
+
}
|
|
45579
|
+
function hexToBytes(hex3) {
|
|
45580
|
+
const h2 = hex3.startsWith("0x") ? hex3.slice(2) : hex3;
|
|
45581
|
+
const bytes = new Uint8Array(h2.length / 2);
|
|
45582
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
45583
|
+
bytes[i2] = parseInt(h2.substr(i2 * 2, 2), 16);
|
|
45584
|
+
}
|
|
45585
|
+
return bytes;
|
|
45586
|
+
}
|
|
45587
|
+
function bytesToHex(bytes) {
|
|
45588
|
+
return Array.from(bytes).map((b2) => b2.toString(16).padStart(2, "0")).join("");
|
|
45589
|
+
}
|
|
45590
|
+
function computeDidHash(didDocument) {
|
|
45591
|
+
const json2 = jcsCanonical(didDocument) ?? "";
|
|
45592
|
+
const bytes = libsodium_wrappers_default.from_string(json2);
|
|
45593
|
+
const hash2 = libsodium_wrappers_default.crypto_hash_sha256(bytes);
|
|
45594
|
+
return "0x" + bytesToHex(hash2);
|
|
45595
|
+
}
|
|
45596
|
+
function verifyMerkleProof(leafHash, proof, merkleRoot) {
|
|
45597
|
+
let current = hexToBytes(leafHash);
|
|
45598
|
+
for (const step of proof) {
|
|
45599
|
+
const sibling2 = hexToBytes(step.hash);
|
|
45600
|
+
const combined = new Uint8Array(current.length + sibling2.length);
|
|
45601
|
+
if (step.position === "left") {
|
|
45602
|
+
combined.set(sibling2);
|
|
45603
|
+
combined.set(current, sibling2.length);
|
|
45604
|
+
} else {
|
|
45605
|
+
combined.set(current);
|
|
45606
|
+
combined.set(sibling2, current.length);
|
|
45607
|
+
}
|
|
45608
|
+
current = libsodium_wrappers_default.crypto_hash_sha256(combined);
|
|
45609
|
+
}
|
|
45610
|
+
const rootBytes = hexToBytes(merkleRoot);
|
|
45611
|
+
if (current.length !== rootBytes.length)
|
|
45612
|
+
return false;
|
|
45613
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
45614
|
+
if (current[i2] !== rootBytes[i2])
|
|
45615
|
+
return false;
|
|
45616
|
+
}
|
|
45617
|
+
return true;
|
|
45618
|
+
}
|
|
45431
45619
|
var init_merkle = __esm({
|
|
45432
45620
|
async "../crypto/dist/merkle.js"() {
|
|
45433
45621
|
"use strict";
|
|
45622
|
+
await init_libsodium_wrappers();
|
|
45434
45623
|
}
|
|
45435
45624
|
});
|
|
45436
45625
|
|
|
45437
45626
|
// ../crypto/dist/vc.js
|
|
45627
|
+
async function sha256(data) {
|
|
45628
|
+
await libsodium_wrappers_default.ready;
|
|
45629
|
+
return libsodium_wrappers_default.crypto_hash_sha256(data);
|
|
45630
|
+
}
|
|
45631
|
+
function base58Encode2(bytes) {
|
|
45632
|
+
let zeros = 0;
|
|
45633
|
+
for (const b2 of bytes) {
|
|
45634
|
+
if (b2 === 0)
|
|
45635
|
+
zeros++;
|
|
45636
|
+
else
|
|
45637
|
+
break;
|
|
45638
|
+
}
|
|
45639
|
+
let num = BigInt(0);
|
|
45640
|
+
for (const b2 of bytes) {
|
|
45641
|
+
num = num * 256n + BigInt(b2);
|
|
45642
|
+
}
|
|
45643
|
+
let result = "";
|
|
45644
|
+
while (num > 0n) {
|
|
45645
|
+
const remainder = Number(num % 58n);
|
|
45646
|
+
num = num / 58n;
|
|
45647
|
+
result = BASE58_ALPHABET2[remainder] + result;
|
|
45648
|
+
}
|
|
45649
|
+
return "1".repeat(zeros) + result;
|
|
45650
|
+
}
|
|
45651
|
+
function base58Decode2(str) {
|
|
45652
|
+
let zeros = 0;
|
|
45653
|
+
for (const c2 of str) {
|
|
45654
|
+
if (c2 === "1")
|
|
45655
|
+
zeros++;
|
|
45656
|
+
else
|
|
45657
|
+
break;
|
|
45658
|
+
}
|
|
45659
|
+
let num = BigInt(0);
|
|
45660
|
+
for (const c2 of str.slice(zeros)) {
|
|
45661
|
+
const idx = BASE58_ALPHABET2.indexOf(c2);
|
|
45662
|
+
if (idx === -1)
|
|
45663
|
+
throw new Error(`Invalid base58 character: ${c2}`);
|
|
45664
|
+
num = num * 58n + BigInt(idx);
|
|
45665
|
+
}
|
|
45666
|
+
const hex3 = num === 0n ? "" : num.toString(16).padStart(2, "0");
|
|
45667
|
+
const paddedHex = hex3.length % 2 ? "0" + hex3 : hex3;
|
|
45668
|
+
const dataBytes = new Uint8Array((paddedHex.match(/.{2}/g) ?? []).map((b2) => parseInt(b2, 16)));
|
|
45669
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
45670
|
+
result.set(dataBytes, zeros);
|
|
45671
|
+
return result;
|
|
45672
|
+
}
|
|
45673
|
+
async function computeHashData(document, proofConfig) {
|
|
45674
|
+
const proofConfigBytes = canonicalize(proofConfig);
|
|
45675
|
+
const proofConfigHash = await sha256(proofConfigBytes);
|
|
45676
|
+
const docWithoutProof = { ...document };
|
|
45677
|
+
delete docWithoutProof.proof;
|
|
45678
|
+
const documentBytes = canonicalize(docWithoutProof);
|
|
45679
|
+
const documentHash = await sha256(documentBytes);
|
|
45680
|
+
const hashData = new Uint8Array(64);
|
|
45681
|
+
hashData.set(proofConfigHash, 0);
|
|
45682
|
+
hashData.set(documentHash, 32);
|
|
45683
|
+
return hashData;
|
|
45684
|
+
}
|
|
45685
|
+
async function signWithDataIntegrity(document, privateKey, verificationMethod, proofPurpose = "assertionMethod", created) {
|
|
45686
|
+
await libsodium_wrappers_default.ready;
|
|
45687
|
+
const timestamp = created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45688
|
+
const proofConfig = {
|
|
45689
|
+
type: "DataIntegrityProof",
|
|
45690
|
+
cryptosuite: CRYPTOSUITE,
|
|
45691
|
+
created: timestamp,
|
|
45692
|
+
verificationMethod,
|
|
45693
|
+
proofPurpose
|
|
45694
|
+
};
|
|
45695
|
+
const hashData = await computeHashData(document, proofConfig);
|
|
45696
|
+
const signature = libsodium_wrappers_default.crypto_sign_detached(hashData, privateKey);
|
|
45697
|
+
const proofValue = "z" + base58Encode2(signature);
|
|
45698
|
+
const proof = {
|
|
45699
|
+
type: "DataIntegrityProof",
|
|
45700
|
+
cryptosuite: CRYPTOSUITE,
|
|
45701
|
+
created: timestamp,
|
|
45702
|
+
verificationMethod,
|
|
45703
|
+
proofPurpose,
|
|
45704
|
+
proofValue
|
|
45705
|
+
};
|
|
45706
|
+
return { ...document, proof };
|
|
45707
|
+
}
|
|
45708
|
+
async function verifyDataIntegrity(document, publicKey) {
|
|
45709
|
+
await libsodium_wrappers_default.ready;
|
|
45710
|
+
const proof = document.proof;
|
|
45711
|
+
if (!proof || proof.type !== "DataIntegrityProof" || proof.cryptosuite !== CRYPTOSUITE) {
|
|
45712
|
+
return false;
|
|
45713
|
+
}
|
|
45714
|
+
if (!proof.proofValue.startsWith("z")) {
|
|
45715
|
+
return false;
|
|
45716
|
+
}
|
|
45717
|
+
const signature = base58Decode2(proof.proofValue.slice(1));
|
|
45718
|
+
if (signature.length !== 64) {
|
|
45719
|
+
return false;
|
|
45720
|
+
}
|
|
45721
|
+
const proofConfig = {
|
|
45722
|
+
type: proof.type,
|
|
45723
|
+
cryptosuite: proof.cryptosuite,
|
|
45724
|
+
created: proof.created,
|
|
45725
|
+
verificationMethod: proof.verificationMethod,
|
|
45726
|
+
proofPurpose: proof.proofPurpose
|
|
45727
|
+
};
|
|
45728
|
+
const hashData = await computeHashData(document, proofConfig);
|
|
45729
|
+
try {
|
|
45730
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(signature, hashData, publicKey);
|
|
45731
|
+
} catch {
|
|
45732
|
+
return false;
|
|
45733
|
+
}
|
|
45734
|
+
}
|
|
45735
|
+
function buildAgentTrustCredential(params) {
|
|
45736
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45737
|
+
return {
|
|
45738
|
+
"@context": [
|
|
45739
|
+
VC_CONTEXT_V2,
|
|
45740
|
+
{
|
|
45741
|
+
AgentTrustCredential: "https://agentvault.chat/vocab#AgentTrustCredential",
|
|
45742
|
+
trustTier: "https://agentvault.chat/vocab#trustTier",
|
|
45743
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore",
|
|
45744
|
+
scoreWindow: "https://agentvault.chat/vocab#scoreWindow",
|
|
45745
|
+
scoreDimensions: "https://agentvault.chat/vocab#scoreDimensions",
|
|
45746
|
+
volume: "https://agentvault.chat/vocab#volume",
|
|
45747
|
+
responsiveness: "https://agentvault.chat/vocab#responsiveness",
|
|
45748
|
+
uptime: "https://agentvault.chat/vocab#uptime",
|
|
45749
|
+
compliance: "https://agentvault.chat/vocab#compliance",
|
|
45750
|
+
verificationEndpoint: "https://agentvault.chat/vocab#verificationEndpoint"
|
|
45751
|
+
}
|
|
45752
|
+
],
|
|
45753
|
+
id: params.credentialId,
|
|
45754
|
+
type: ["VerifiableCredential", "AgentTrustCredential"],
|
|
45755
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45756
|
+
validFrom: params.validFrom ?? now,
|
|
45757
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45758
|
+
credentialSubject: {
|
|
45759
|
+
id: params.subjectDid,
|
|
45760
|
+
trustTier: params.trustTier,
|
|
45761
|
+
compositeScore: params.compositeScore,
|
|
45762
|
+
scoreWindow: params.scoreWindow,
|
|
45763
|
+
...params.dimensions ? {
|
|
45764
|
+
scoreDimensions: {
|
|
45765
|
+
volume: params.dimensions.volume,
|
|
45766
|
+
responsiveness: params.dimensions.responsiveness,
|
|
45767
|
+
uptime: params.dimensions.uptime,
|
|
45768
|
+
compliance: params.dimensions.compliance
|
|
45769
|
+
}
|
|
45770
|
+
} : {},
|
|
45771
|
+
...params.verificationEndpoint ? { verificationEndpoint: params.verificationEndpoint } : {}
|
|
45772
|
+
}
|
|
45773
|
+
};
|
|
45774
|
+
}
|
|
45775
|
+
function buildSkillAttestation(params) {
|
|
45776
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45777
|
+
return {
|
|
45778
|
+
"@context": [
|
|
45779
|
+
VC_CONTEXT_V2,
|
|
45780
|
+
{
|
|
45781
|
+
SkillAttestation: "https://agentvault.chat/vocab#SkillAttestation",
|
|
45782
|
+
skillName: "https://agentvault.chat/vocab#skillName",
|
|
45783
|
+
skillNamespace: "https://agentvault.chat/vocab#skillNamespace",
|
|
45784
|
+
proficiencyLevel: "https://agentvault.chat/vocab#proficiencyLevel",
|
|
45785
|
+
totalInvocations: "https://agentvault.chat/vocab#totalInvocations",
|
|
45786
|
+
successRate: "https://agentvault.chat/vocab#successRate",
|
|
45787
|
+
assessedAt: "https://agentvault.chat/vocab#assessedAt"
|
|
45788
|
+
}
|
|
45789
|
+
],
|
|
45790
|
+
id: params.credentialId,
|
|
45791
|
+
type: ["VerifiableCredential", "SkillAttestation"],
|
|
45792
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45793
|
+
validFrom: params.validFrom ?? now,
|
|
45794
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45795
|
+
credentialSubject: {
|
|
45796
|
+
id: params.subjectDid,
|
|
45797
|
+
skillName: params.skillName,
|
|
45798
|
+
skillNamespace: params.skillNamespace,
|
|
45799
|
+
...params.proficiencyLevel ? { proficiencyLevel: params.proficiencyLevel } : {},
|
|
45800
|
+
...params.totalInvocations !== void 0 ? { totalInvocations: params.totalInvocations } : {},
|
|
45801
|
+
...params.successRate !== void 0 ? { successRate: params.successRate } : {},
|
|
45802
|
+
...params.assessedAt ? { assessedAt: params.assessedAt } : {}
|
|
45803
|
+
}
|
|
45804
|
+
};
|
|
45805
|
+
}
|
|
45806
|
+
function buildPerformanceRecord(params) {
|
|
45807
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45808
|
+
return {
|
|
45809
|
+
"@context": [
|
|
45810
|
+
VC_CONTEXT_V2,
|
|
45811
|
+
{
|
|
45812
|
+
PerformanceRecord: "https://agentvault.chat/vocab#PerformanceRecord",
|
|
45813
|
+
periodStart: "https://agentvault.chat/vocab#periodStart",
|
|
45814
|
+
periodEnd: "https://agentvault.chat/vocab#periodEnd",
|
|
45815
|
+
messagesHandled: "https://agentvault.chat/vocab#messagesHandled",
|
|
45816
|
+
avgResponseTimeMs: "https://agentvault.chat/vocab#avgResponseTimeMs",
|
|
45817
|
+
uptimePercentage: "https://agentvault.chat/vocab#uptimePercentage",
|
|
45818
|
+
policyViolations: "https://agentvault.chat/vocab#policyViolations",
|
|
45819
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore"
|
|
45820
|
+
}
|
|
45821
|
+
],
|
|
45822
|
+
id: params.credentialId,
|
|
45823
|
+
type: ["VerifiableCredential", "PerformanceRecord"],
|
|
45824
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45825
|
+
validFrom: params.validFrom ?? now,
|
|
45826
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45827
|
+
credentialSubject: {
|
|
45828
|
+
id: params.subjectDid,
|
|
45829
|
+
periodStart: params.periodStart,
|
|
45830
|
+
periodEnd: params.periodEnd,
|
|
45831
|
+
messagesHandled: params.messagesHandled,
|
|
45832
|
+
avgResponseTimeMs: params.avgResponseTimeMs,
|
|
45833
|
+
uptimePercentage: params.uptimePercentage,
|
|
45834
|
+
policyViolations: params.policyViolations,
|
|
45835
|
+
compositeScore: params.compositeScore
|
|
45836
|
+
}
|
|
45837
|
+
};
|
|
45838
|
+
}
|
|
45839
|
+
function buildAgentTrustReportCredential(params) {
|
|
45840
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45841
|
+
const subject = {
|
|
45842
|
+
id: params.subjectDid,
|
|
45843
|
+
reportPeriod: {
|
|
45844
|
+
start: params.reportPeriodStart,
|
|
45845
|
+
end: params.reportPeriodEnd
|
|
45846
|
+
},
|
|
45847
|
+
trustTier: params.trustTier,
|
|
45848
|
+
compositeScore: params.compositeScore
|
|
45849
|
+
};
|
|
45850
|
+
if (params.dimensions)
|
|
45851
|
+
subject.dimensions = params.dimensions;
|
|
45852
|
+
if (params.trending)
|
|
45853
|
+
subject.trending = params.trending;
|
|
45854
|
+
if (params.fleetComparison)
|
|
45855
|
+
subject.fleetComparison = params.fleetComparison;
|
|
45856
|
+
if (params.driftStatus)
|
|
45857
|
+
subject.driftStatus = params.driftStatus;
|
|
45858
|
+
if (params.auditIntegrity)
|
|
45859
|
+
subject.auditIntegrity = params.auditIntegrity;
|
|
45860
|
+
if (params.telemetrySummary)
|
|
45861
|
+
subject.telemetrySummary = params.telemetrySummary;
|
|
45862
|
+
if (params.verificationEndpoint)
|
|
45863
|
+
subject.verificationEndpoint = params.verificationEndpoint;
|
|
45864
|
+
return {
|
|
45865
|
+
"@context": [
|
|
45866
|
+
VC_CONTEXT_V2,
|
|
45867
|
+
{
|
|
45868
|
+
AgentTrustReport: "https://agentvault.chat/vocab#AgentTrustReport",
|
|
45869
|
+
reportPeriod: "https://agentvault.chat/vocab#reportPeriod",
|
|
45870
|
+
trustTier: "https://agentvault.chat/vocab#trustTier",
|
|
45871
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore",
|
|
45872
|
+
dimensions: "https://agentvault.chat/vocab#dimensions",
|
|
45873
|
+
trending: "https://agentvault.chat/vocab#trending",
|
|
45874
|
+
fleetComparison: "https://agentvault.chat/vocab#fleetComparison",
|
|
45875
|
+
driftStatus: "https://agentvault.chat/vocab#driftStatus",
|
|
45876
|
+
auditIntegrity: "https://agentvault.chat/vocab#auditIntegrity",
|
|
45877
|
+
telemetrySummary: "https://agentvault.chat/vocab#telemetrySummary",
|
|
45878
|
+
verificationEndpoint: "https://agentvault.chat/vocab#verificationEndpoint"
|
|
45879
|
+
}
|
|
45880
|
+
],
|
|
45881
|
+
id: params.credentialId,
|
|
45882
|
+
type: ["VerifiableCredential", "AgentTrustReport"],
|
|
45883
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45884
|
+
validFrom: params.validFrom ?? now,
|
|
45885
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45886
|
+
credentialSubject: subject
|
|
45887
|
+
};
|
|
45888
|
+
}
|
|
45889
|
+
function buildVerifiablePresentation(holderDid, credentials, presentationId) {
|
|
45890
|
+
return {
|
|
45891
|
+
"@context": [VC_CONTEXT_V2],
|
|
45892
|
+
type: "VerifiablePresentation",
|
|
45893
|
+
...presentationId ? { id: presentationId } : {},
|
|
45894
|
+
holder: holderDid,
|
|
45895
|
+
verifiableCredential: credentials
|
|
45896
|
+
};
|
|
45897
|
+
}
|
|
45898
|
+
async function issueCredential(credential, privateKey, verificationMethod) {
|
|
45899
|
+
return signWithDataIntegrity(credential, privateKey, verificationMethod, "assertionMethod");
|
|
45900
|
+
}
|
|
45901
|
+
async function presentCredentials(presentation, privateKey, verificationMethod) {
|
|
45902
|
+
return signWithDataIntegrity(presentation, privateKey, verificationMethod, "authentication");
|
|
45903
|
+
}
|
|
45904
|
+
var VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2;
|
|
45438
45905
|
var init_vc = __esm({
|
|
45439
45906
|
async "../crypto/dist/vc.js"() {
|
|
45440
45907
|
"use strict";
|
|
45908
|
+
await init_libsodium_wrappers();
|
|
45441
45909
|
await init_did();
|
|
45910
|
+
VC_CONTEXT_V2 = "https://www.w3.org/ns/credentials/v2";
|
|
45911
|
+
AV_CREDENTIAL_CONTEXT = "https://agentvault.chat/ns/credentials/v1";
|
|
45912
|
+
CRYPTOSUITE = "eddsa-jcs-2022";
|
|
45913
|
+
BASE58_ALPHABET2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
45442
45914
|
}
|
|
45443
45915
|
});
|
|
45444
45916
|
|
|
45445
45917
|
// ../crypto/dist/transport.js
|
|
45446
|
-
function
|
|
45918
|
+
function hexToBytes2(hex3) {
|
|
45447
45919
|
return libsodium_wrappers_default.from_hex(hex3);
|
|
45448
45920
|
}
|
|
45449
|
-
function
|
|
45921
|
+
function bytesToHex2(bytes) {
|
|
45450
45922
|
return libsodium_wrappers_default.to_hex(bytes);
|
|
45451
45923
|
}
|
|
45452
45924
|
function base64ToBytes(b64) {
|
|
@@ -45484,6 +45956,70 @@ function transportToEncryptedMessage(transport) {
|
|
|
45484
45956
|
ciphertext: base64ToBytes(transport.ciphertext)
|
|
45485
45957
|
};
|
|
45486
45958
|
}
|
|
45959
|
+
function encryptedMessageToTransportV2(msg) {
|
|
45960
|
+
if (!msg.encryptedHeader || !msg.headerNonce) {
|
|
45961
|
+
throw new Error("encryptedMessageToTransportV2 requires v2 encrypted message");
|
|
45962
|
+
}
|
|
45963
|
+
return {
|
|
45964
|
+
envelope_version: "2.0.0",
|
|
45965
|
+
encrypted_header: bytesToBase64(msg.encryptedHeader),
|
|
45966
|
+
header_nonce: bytesToBase64(msg.headerNonce),
|
|
45967
|
+
header_signature: bytesToBase64(msg.headerSignature),
|
|
45968
|
+
nonce: bytesToBase64(msg.nonce),
|
|
45969
|
+
ciphertext: bytesToBase64(msg.ciphertext)
|
|
45970
|
+
};
|
|
45971
|
+
}
|
|
45972
|
+
function transportV2ToEncryptedMessage(transport, plaintextHeader) {
|
|
45973
|
+
return {
|
|
45974
|
+
header: plaintextHeader,
|
|
45975
|
+
headerSignature: base64ToBytes(transport.header_signature),
|
|
45976
|
+
ciphertext: base64ToBytes(transport.ciphertext),
|
|
45977
|
+
nonce: base64ToBytes(transport.nonce),
|
|
45978
|
+
envelopeVersion: "2.0.0",
|
|
45979
|
+
encryptedHeader: base64ToBytes(transport.encrypted_header),
|
|
45980
|
+
headerNonce: base64ToBytes(transport.header_nonce)
|
|
45981
|
+
};
|
|
45982
|
+
}
|
|
45983
|
+
function encryptedMessageToTransportV2Full(msg) {
|
|
45984
|
+
if (!msg.encryptedHeader || !msg.headerNonce) {
|
|
45985
|
+
throw new Error("encryptedMessageToTransportV2Full requires v2 encrypted message");
|
|
45986
|
+
}
|
|
45987
|
+
const v1 = encryptedMessageToTransport(msg);
|
|
45988
|
+
return {
|
|
45989
|
+
...v1,
|
|
45990
|
+
envelope_version: "2.0.0",
|
|
45991
|
+
encrypted_header: bytesToBase64(msg.encryptedHeader),
|
|
45992
|
+
header_nonce: bytesToBase64(msg.headerNonce)
|
|
45993
|
+
};
|
|
45994
|
+
}
|
|
45995
|
+
function encryptedMessageToHexTransport(msg) {
|
|
45996
|
+
const headerObj = {
|
|
45997
|
+
dhPublicKey: bytesToHex2(msg.header.dhPublicKey),
|
|
45998
|
+
previousChainLength: msg.header.previousChainLength,
|
|
45999
|
+
messageNumber: msg.header.messageNumber
|
|
46000
|
+
};
|
|
46001
|
+
const headerBlobHex = Buffer.from(JSON.stringify(headerObj)).toString("hex");
|
|
46002
|
+
return {
|
|
46003
|
+
header_blob: headerBlobHex,
|
|
46004
|
+
header_signature: bytesToHex2(msg.headerSignature),
|
|
46005
|
+
ciphertext: bytesToHex2(msg.ciphertext),
|
|
46006
|
+
nonce: bytesToHex2(msg.nonce)
|
|
46007
|
+
};
|
|
46008
|
+
}
|
|
46009
|
+
function hexTransportToEncryptedMessage(transport) {
|
|
46010
|
+
const headerJson = Buffer.from(transport.header_blob, "hex").toString("utf-8");
|
|
46011
|
+
const headerObj = JSON.parse(headerJson);
|
|
46012
|
+
return {
|
|
46013
|
+
header: {
|
|
46014
|
+
dhPublicKey: hexToBytes2(headerObj.dhPublicKey),
|
|
46015
|
+
previousChainLength: headerObj.previousChainLength,
|
|
46016
|
+
messageNumber: headerObj.messageNumber
|
|
46017
|
+
},
|
|
46018
|
+
headerSignature: hexToBytes2(transport.header_signature),
|
|
46019
|
+
ciphertext: hexToBytes2(transport.ciphertext),
|
|
46020
|
+
nonce: hexToBytes2(transport.nonce)
|
|
46021
|
+
};
|
|
46022
|
+
}
|
|
45487
46023
|
var init_transport = __esm({
|
|
45488
46024
|
async "../crypto/dist/transport.js"() {
|
|
45489
46025
|
"use strict";
|
|
@@ -45747,6 +46283,33 @@ function buildEvalSpan(opts) {
|
|
|
45747
46283
|
status: { code: 0 }
|
|
45748
46284
|
};
|
|
45749
46285
|
}
|
|
46286
|
+
function buildForgeSpan(opts) {
|
|
46287
|
+
const now = Date.now();
|
|
46288
|
+
const attributes = {
|
|
46289
|
+
"ai.agent.forge.session_id": opts.forgeSessionId,
|
|
46290
|
+
"ai.agent.forge.phase": opts.phase
|
|
46291
|
+
};
|
|
46292
|
+
if (opts.stageNumber !== void 0)
|
|
46293
|
+
attributes["ai.agent.forge.stage_number"] = opts.stageNumber;
|
|
46294
|
+
if (opts.artifactCount !== void 0)
|
|
46295
|
+
attributes["ai.agent.forge.artifact_count"] = opts.artifactCount;
|
|
46296
|
+
if (opts.scanStatus !== void 0)
|
|
46297
|
+
attributes["ai.agent.forge.scan_status"] = opts.scanStatus;
|
|
46298
|
+
applySkillName(attributes, opts.skillName);
|
|
46299
|
+
const isError = opts.status === "error";
|
|
46300
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46301
|
+
return {
|
|
46302
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46303
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46304
|
+
parentSpanId: opts.parentSpanId,
|
|
46305
|
+
name: `forge.${opts.phase}`,
|
|
46306
|
+
kind: "internal",
|
|
46307
|
+
startTime: now - opts.latencyMs,
|
|
46308
|
+
endTime: now,
|
|
46309
|
+
attributes,
|
|
46310
|
+
status
|
|
46311
|
+
};
|
|
46312
|
+
}
|
|
45750
46313
|
function buildPolicyViolationSpan(opts) {
|
|
45751
46314
|
const now = Date.now();
|
|
45752
46315
|
const attributes = {
|
|
@@ -45772,12 +46335,309 @@ function buildPolicyViolationSpan(opts) {
|
|
|
45772
46335
|
startTime: now,
|
|
45773
46336
|
endTime: now,
|
|
45774
46337
|
attributes,
|
|
45775
|
-
status: isBlock ? { code: 2, message: `Policy violation: ${opts.violationType}` } : { code: 0 }
|
|
46338
|
+
status: isBlock ? { code: 2, message: `Policy violation: ${opts.violationType}` } : { code: 0 }
|
|
46339
|
+
};
|
|
46340
|
+
}
|
|
46341
|
+
function buildDecisionSpan(opts) {
|
|
46342
|
+
const now = Date.now();
|
|
46343
|
+
const attributes = {
|
|
46344
|
+
"av.decision.id": opts.decisionId,
|
|
46345
|
+
"av.decision.phase": opts.phase
|
|
46346
|
+
};
|
|
46347
|
+
if (opts.priority)
|
|
46348
|
+
attributes["av.decision.priority"] = opts.priority;
|
|
46349
|
+
if (opts.category)
|
|
46350
|
+
attributes["av.decision.category"] = opts.category;
|
|
46351
|
+
applySkillName(attributes, opts.skillName);
|
|
46352
|
+
const isError = opts.status === "error";
|
|
46353
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46354
|
+
return {
|
|
46355
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46356
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46357
|
+
parentSpanId: opts.parentSpanId,
|
|
46358
|
+
name: "av.decision",
|
|
46359
|
+
kind: "internal",
|
|
46360
|
+
startTime: now - opts.latencyMs,
|
|
46361
|
+
endTime: now,
|
|
46362
|
+
attributes,
|
|
46363
|
+
status
|
|
46364
|
+
};
|
|
46365
|
+
}
|
|
46366
|
+
function buildResyncSpan(opts) {
|
|
46367
|
+
const now = Date.now();
|
|
46368
|
+
const attributes = {
|
|
46369
|
+
"av.resync.conversation_id": opts.conversationId,
|
|
46370
|
+
"av.resync.phase": opts.phase
|
|
46371
|
+
};
|
|
46372
|
+
if (opts.reason)
|
|
46373
|
+
attributes["av.resync.reason"] = opts.reason;
|
|
46374
|
+
applySkillName(attributes, opts.skillName);
|
|
46375
|
+
const isError = opts.status === "error";
|
|
46376
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46377
|
+
return {
|
|
46378
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46379
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46380
|
+
parentSpanId: opts.parentSpanId,
|
|
46381
|
+
name: "av.resync",
|
|
46382
|
+
kind: "internal",
|
|
46383
|
+
startTime: now - opts.latencyMs,
|
|
46384
|
+
endTime: now,
|
|
46385
|
+
attributes,
|
|
46386
|
+
status
|
|
46387
|
+
};
|
|
46388
|
+
}
|
|
46389
|
+
function buildA2aSpan(opts) {
|
|
46390
|
+
const now = Date.now();
|
|
46391
|
+
const attributes = {
|
|
46392
|
+
"av.a2a.channel_id": opts.channelId,
|
|
46393
|
+
"av.a2a.operation": opts.operation
|
|
46394
|
+
};
|
|
46395
|
+
if (opts.peerHubAddress)
|
|
46396
|
+
attributes["av.a2a.peer_hub_address"] = opts.peerHubAddress;
|
|
46397
|
+
if (opts.role)
|
|
46398
|
+
attributes["av.a2a.role"] = opts.role;
|
|
46399
|
+
applySkillName(attributes, opts.skillName);
|
|
46400
|
+
const isError = opts.status === "error";
|
|
46401
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46402
|
+
return {
|
|
46403
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46404
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46405
|
+
parentSpanId: opts.parentSpanId,
|
|
46406
|
+
name: "av.a2a",
|
|
46407
|
+
kind: "internal",
|
|
46408
|
+
startTime: now - opts.latencyMs,
|
|
46409
|
+
endTime: now,
|
|
46410
|
+
attributes,
|
|
46411
|
+
status
|
|
46412
|
+
};
|
|
46413
|
+
}
|
|
46414
|
+
function buildScanSpan(opts) {
|
|
46415
|
+
const now = Date.now();
|
|
46416
|
+
const attributes = {
|
|
46417
|
+
"av.scan.target": opts.scanTarget,
|
|
46418
|
+
"av.scan.type": opts.scanType,
|
|
46419
|
+
"av.scan.violation_count": opts.violationCount,
|
|
46420
|
+
"av.scan.rule_count": opts.ruleCount
|
|
46421
|
+
};
|
|
46422
|
+
applySkillName(attributes, opts.skillName);
|
|
46423
|
+
const isError = opts.status === "error" || opts.violationCount > 0;
|
|
46424
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46425
|
+
return {
|
|
46426
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46427
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46428
|
+
parentSpanId: opts.parentSpanId,
|
|
46429
|
+
name: "av.scan",
|
|
46430
|
+
kind: "internal",
|
|
46431
|
+
startTime: now - opts.latencyMs,
|
|
46432
|
+
endTime: now,
|
|
46433
|
+
attributes,
|
|
46434
|
+
status
|
|
46435
|
+
};
|
|
46436
|
+
}
|
|
46437
|
+
function buildWorkspaceSpan(opts) {
|
|
46438
|
+
const now = Date.now();
|
|
46439
|
+
const attributes = {
|
|
46440
|
+
"av.workspace.id": opts.workspaceId,
|
|
46441
|
+
"av.workspace.operation": opts.operation
|
|
46442
|
+
};
|
|
46443
|
+
if (opts.fileName)
|
|
46444
|
+
attributes["av.workspace.file_name"] = opts.fileName;
|
|
46445
|
+
if (opts.fileSizeBytes !== void 0)
|
|
46446
|
+
attributes["av.workspace.file_size_bytes"] = opts.fileSizeBytes;
|
|
46447
|
+
if (opts.encrypted !== void 0)
|
|
46448
|
+
attributes["av.workspace.encrypted"] = opts.encrypted;
|
|
46449
|
+
applySkillName(attributes, opts.skillName);
|
|
46450
|
+
const isError = opts.status === "error";
|
|
46451
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46452
|
+
return {
|
|
46453
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46454
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46455
|
+
parentSpanId: opts.parentSpanId,
|
|
46456
|
+
name: "av.workspace",
|
|
46457
|
+
kind: "internal",
|
|
46458
|
+
startTime: now - opts.latencyMs,
|
|
46459
|
+
endTime: now,
|
|
46460
|
+
attributes,
|
|
46461
|
+
status
|
|
46462
|
+
};
|
|
46463
|
+
}
|
|
46464
|
+
function buildCapabilitySpan(opts) {
|
|
46465
|
+
const now = Date.now();
|
|
46466
|
+
const attributes = {
|
|
46467
|
+
"av.skill.operation": opts.operation,
|
|
46468
|
+
"av.skill.success": opts.success
|
|
46469
|
+
};
|
|
46470
|
+
if (opts.skillName)
|
|
46471
|
+
attributes["av.skill.name"] = opts.skillName;
|
|
46472
|
+
if (opts.version)
|
|
46473
|
+
attributes["av.skill.version"] = opts.version;
|
|
46474
|
+
if (opts.certificationTier)
|
|
46475
|
+
attributes["av.skill.certification_tier"] = opts.certificationTier;
|
|
46476
|
+
if (opts.toolsUsed?.length)
|
|
46477
|
+
attributes["av.skill.tools_used"] = opts.toolsUsed.join(",");
|
|
46478
|
+
const status = opts.success ? { code: 0 } : { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} };
|
|
46479
|
+
return {
|
|
46480
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46481
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46482
|
+
parentSpanId: opts.parentSpanId,
|
|
46483
|
+
name: "av.skill.invoke",
|
|
46484
|
+
kind: "internal",
|
|
46485
|
+
startTime: now - opts.latencyMs,
|
|
46486
|
+
endTime: now,
|
|
46487
|
+
attributes,
|
|
46488
|
+
status
|
|
46489
|
+
};
|
|
46490
|
+
}
|
|
46491
|
+
function buildEnrollmentSpan(opts) {
|
|
46492
|
+
const now = Date.now();
|
|
46493
|
+
const attributes = {
|
|
46494
|
+
"av.enrollment.phase": opts.phase
|
|
46495
|
+
};
|
|
46496
|
+
if (opts.deviceId)
|
|
46497
|
+
attributes["av.enrollment.device_id"] = opts.deviceId;
|
|
46498
|
+
if (opts.enrollmentType)
|
|
46499
|
+
attributes["av.enrollment.type"] = opts.enrollmentType;
|
|
46500
|
+
applySkillName(attributes, opts.skillName);
|
|
46501
|
+
const isError = opts.status === "error" || opts.phase === "fail";
|
|
46502
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46503
|
+
return {
|
|
46504
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46505
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46506
|
+
parentSpanId: opts.parentSpanId,
|
|
46507
|
+
name: "av.enrollment",
|
|
46508
|
+
kind: "internal",
|
|
46509
|
+
startTime: now - opts.latencyMs,
|
|
46510
|
+
endTime: now,
|
|
46511
|
+
attributes,
|
|
46512
|
+
status
|
|
46513
|
+
};
|
|
46514
|
+
}
|
|
46515
|
+
function buildRoomSpan(opts) {
|
|
46516
|
+
const now = Date.now();
|
|
46517
|
+
const attributes = {
|
|
46518
|
+
"av.room.id": opts.roomId,
|
|
46519
|
+
"av.room.operation": opts.operation
|
|
46520
|
+
};
|
|
46521
|
+
if (opts.roomName)
|
|
46522
|
+
attributes["av.room.name"] = opts.roomName;
|
|
46523
|
+
if (opts.memberCount !== void 0)
|
|
46524
|
+
attributes["av.room.member_count"] = opts.memberCount;
|
|
46525
|
+
applySkillName(attributes, opts.skillName);
|
|
46526
|
+
const isError = opts.status === "error";
|
|
46527
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46528
|
+
return {
|
|
46529
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46530
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46531
|
+
parentSpanId: opts.parentSpanId,
|
|
46532
|
+
name: "av.room",
|
|
46533
|
+
kind: "internal",
|
|
46534
|
+
startTime: now - opts.latencyMs,
|
|
46535
|
+
endTime: now,
|
|
46536
|
+
attributes,
|
|
46537
|
+
status
|
|
46538
|
+
};
|
|
46539
|
+
}
|
|
46540
|
+
function buildTrustSpan(opts) {
|
|
46541
|
+
const now = Date.now();
|
|
46542
|
+
const attributes = {
|
|
46543
|
+
"av.trust.agent_hub_address": opts.agentHubAddress,
|
|
46544
|
+
"av.trust.operation": opts.operation
|
|
46545
|
+
};
|
|
46546
|
+
if (opts.previousTier)
|
|
46547
|
+
attributes["av.trust.previous_tier"] = opts.previousTier;
|
|
46548
|
+
if (opts.newTier)
|
|
46549
|
+
attributes["av.trust.new_tier"] = opts.newTier;
|
|
46550
|
+
if (opts.overallScore !== void 0)
|
|
46551
|
+
attributes["av.trust.overall_score"] = opts.overallScore;
|
|
46552
|
+
if (opts.dimension)
|
|
46553
|
+
attributes["av.trust.dimension"] = opts.dimension;
|
|
46554
|
+
if (opts.dimensionScore !== void 0)
|
|
46555
|
+
attributes["av.trust.dimension_score"] = opts.dimensionScore;
|
|
46556
|
+
applySkillName(attributes, opts.skillName);
|
|
46557
|
+
const isError = opts.status === "error";
|
|
46558
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46559
|
+
return {
|
|
46560
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46561
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46562
|
+
parentSpanId: opts.parentSpanId,
|
|
46563
|
+
name: "av.trust",
|
|
46564
|
+
kind: "internal",
|
|
46565
|
+
startTime: now - opts.latencyMs,
|
|
46566
|
+
endTime: now,
|
|
46567
|
+
attributes,
|
|
46568
|
+
status
|
|
46569
|
+
};
|
|
46570
|
+
}
|
|
46571
|
+
function buildEvalRunSpan(opts) {
|
|
46572
|
+
const now = Date.now();
|
|
46573
|
+
const attributes = {
|
|
46574
|
+
"av.eval.scenario_id": opts.scenarioId,
|
|
46575
|
+
"av.eval.agent_id": opts.agentId,
|
|
46576
|
+
"av.eval.status": opts.status,
|
|
46577
|
+
"av.eval.latency_ms": opts.latencyMs
|
|
46578
|
+
};
|
|
46579
|
+
if (opts.scenarioName)
|
|
46580
|
+
attributes["av.eval.scenario_name"] = opts.scenarioName;
|
|
46581
|
+
if (opts.variationType)
|
|
46582
|
+
attributes["av.eval.variation_type"] = opts.variationType;
|
|
46583
|
+
if (opts.shiftMagnitude !== void 0)
|
|
46584
|
+
attributes["av.eval.shift_magnitude"] = opts.shiftMagnitude;
|
|
46585
|
+
if (opts.outcomeMatch !== void 0)
|
|
46586
|
+
attributes["av.eval.outcome_match"] = opts.outcomeMatch;
|
|
46587
|
+
if (opts.flagged !== void 0)
|
|
46588
|
+
attributes["av.eval.flagged"] = opts.flagged;
|
|
46589
|
+
if (opts.flagReason)
|
|
46590
|
+
attributes["av.eval.flag_reason"] = opts.flagReason;
|
|
46591
|
+
const isError = opts.status === "failed";
|
|
46592
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46593
|
+
return {
|
|
46594
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46595
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46596
|
+
parentSpanId: opts.parentSpanId,
|
|
46597
|
+
name: "av.eval.run",
|
|
46598
|
+
kind: "internal",
|
|
46599
|
+
startTime: now - opts.latencyMs,
|
|
46600
|
+
endTime: now,
|
|
46601
|
+
attributes,
|
|
46602
|
+
status
|
|
45776
46603
|
};
|
|
45777
46604
|
}
|
|
45778
46605
|
function buildTraceparent(span) {
|
|
45779
46606
|
return `00-${span.traceId}-${span.spanId}-01`;
|
|
45780
46607
|
}
|
|
46608
|
+
function parseTraceparent(header) {
|
|
46609
|
+
const parts = header.split("-");
|
|
46610
|
+
if (parts.length !== 4)
|
|
46611
|
+
return null;
|
|
46612
|
+
const [version2, traceId, parentId, traceFlags] = parts;
|
|
46613
|
+
if (!version2 || !traceId || !parentId || !traceFlags)
|
|
46614
|
+
return null;
|
|
46615
|
+
if (traceId.length !== 32 || parentId.length !== 16)
|
|
46616
|
+
return null;
|
|
46617
|
+
return { version: version2, traceId, parentId, traceFlags };
|
|
46618
|
+
}
|
|
46619
|
+
function spanToTraceContext(span, tracestate) {
|
|
46620
|
+
return {
|
|
46621
|
+
traceparent: buildTraceparent(span),
|
|
46622
|
+
tracestate: tracestate ?? `av=s:${span.spanId}`
|
|
46623
|
+
};
|
|
46624
|
+
}
|
|
46625
|
+
function propagateContext(incomingTraceparent) {
|
|
46626
|
+
const parsed = parseTraceparent(incomingTraceparent);
|
|
46627
|
+
if (!parsed)
|
|
46628
|
+
return null;
|
|
46629
|
+
return {
|
|
46630
|
+
traceId: parsed.traceId,
|
|
46631
|
+
parentSpanId: parsed.parentId,
|
|
46632
|
+
spanId: generateSpanId()
|
|
46633
|
+
};
|
|
46634
|
+
}
|
|
46635
|
+
function spanToW3CHeaders(span, tracestate) {
|
|
46636
|
+
return {
|
|
46637
|
+
traceparent: buildTraceparent(span),
|
|
46638
|
+
tracestate: tracestate ?? `av=s:${span.spanId}`
|
|
46639
|
+
};
|
|
46640
|
+
}
|
|
45781
46641
|
var init_telemetry = __esm({
|
|
45782
46642
|
"../crypto/dist/telemetry.js"() {
|
|
45783
46643
|
"use strict";
|
|
@@ -45948,6 +46808,29 @@ var init_telemetry_reporter = __esm({
|
|
|
45948
46808
|
});
|
|
45949
46809
|
|
|
45950
46810
|
// ../crypto/dist/backup.js
|
|
46811
|
+
async function generateBackupCode() {
|
|
46812
|
+
await libsodium_wrappers_default.ready;
|
|
46813
|
+
const bytes = libsodium_wrappers_default.randombytes_buf(13);
|
|
46814
|
+
let bits = 0n;
|
|
46815
|
+
for (const b2 of bytes) {
|
|
46816
|
+
bits = bits << 8n | BigInt(b2);
|
|
46817
|
+
}
|
|
46818
|
+
bits >>= 4n;
|
|
46819
|
+
let code = "";
|
|
46820
|
+
for (let i2 = 0; i2 < 20; i2++) {
|
|
46821
|
+
const idx = Number(bits & 0x1fn);
|
|
46822
|
+
code = CROCKFORD[idx] + code;
|
|
46823
|
+
bits >>= 5n;
|
|
46824
|
+
}
|
|
46825
|
+
return code;
|
|
46826
|
+
}
|
|
46827
|
+
function formatBackupCode(code) {
|
|
46828
|
+
const clean5 = code.replace(/[-\s]/g, "").toUpperCase();
|
|
46829
|
+
return clean5.match(/.{1,4}/g)?.join("-") ?? clean5;
|
|
46830
|
+
}
|
|
46831
|
+
function normalizeBackupCode(input) {
|
|
46832
|
+
return input.replace(/[-\s]/g, "").toUpperCase();
|
|
46833
|
+
}
|
|
45951
46834
|
async function deriveBackupKey(code, salt) {
|
|
45952
46835
|
await libsodium_wrappers_default.ready;
|
|
45953
46836
|
return libsodium_wrappers_default.crypto_pwhash(KEY_BYTES, code, salt, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, libsodium_wrappers_default.crypto_pwhash_ALG_ARGON2ID13);
|
|
@@ -45969,28 +46852,88 @@ async function encryptBackupWithKey(bundle, key, salt) {
|
|
|
45969
46852
|
result.set(ciphertext, SALT_BYTES + NONCE_BYTES);
|
|
45970
46853
|
return result;
|
|
45971
46854
|
}
|
|
46855
|
+
async function decryptBackup(encrypted, code) {
|
|
46856
|
+
await libsodium_wrappers_default.ready;
|
|
46857
|
+
const minLen = SALT_BYTES + NONCE_BYTES + libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_ABYTES;
|
|
46858
|
+
if (encrypted.length < minLen) {
|
|
46859
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46860
|
+
}
|
|
46861
|
+
const salt = encrypted.slice(0, SALT_BYTES);
|
|
46862
|
+
const nonce = encrypted.slice(SALT_BYTES, SALT_BYTES + NONCE_BYTES);
|
|
46863
|
+
const ciphertext = encrypted.slice(SALT_BYTES + NONCE_BYTES);
|
|
46864
|
+
const key = await deriveBackupKey(code, salt);
|
|
46865
|
+
let plaintext;
|
|
46866
|
+
try {
|
|
46867
|
+
plaintext = libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_decrypt(null, ciphertext, null, nonce, key);
|
|
46868
|
+
} catch {
|
|
46869
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46870
|
+
}
|
|
46871
|
+
let bundle;
|
|
46872
|
+
try {
|
|
46873
|
+
bundle = JSON.parse(libsodium_wrappers_default.to_string(plaintext));
|
|
46874
|
+
} catch {
|
|
46875
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46876
|
+
}
|
|
46877
|
+
if (bundle.version !== BACKUP_VERSION) {
|
|
46878
|
+
throw new Error(`Unsupported backup version: ${bundle.version}`);
|
|
46879
|
+
}
|
|
46880
|
+
return bundle;
|
|
46881
|
+
}
|
|
45972
46882
|
async function hashBackupCode(code) {
|
|
45973
46883
|
await libsodium_wrappers_default.ready;
|
|
45974
46884
|
return libsodium_wrappers_default.crypto_generichash(32, libsodium_wrappers_default.from_string(code));
|
|
45975
46885
|
}
|
|
45976
|
-
var ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, MAX_BACKUP_SIZE;
|
|
46886
|
+
var CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE;
|
|
45977
46887
|
var init_backup = __esm({
|
|
45978
46888
|
async "../crypto/dist/backup.js"() {
|
|
45979
46889
|
"use strict";
|
|
45980
46890
|
await init_libsodium_wrappers();
|
|
46891
|
+
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
45981
46892
|
ARGON2_OPSLIMIT = 2;
|
|
45982
46893
|
ARGON2_MEMLIMIT = 67108864;
|
|
45983
46894
|
SALT_BYTES = 16;
|
|
45984
46895
|
NONCE_BYTES = 24;
|
|
45985
46896
|
KEY_BYTES = 32;
|
|
46897
|
+
BACKUP_VERSION = 1;
|
|
45986
46898
|
MAX_BACKUP_SIZE = 512 * 1024;
|
|
45987
46899
|
}
|
|
45988
46900
|
});
|
|
45989
46901
|
|
|
45990
46902
|
// ../crypto/dist/approval.js
|
|
46903
|
+
async function createApprovalArtifact(content, privateKeyHex) {
|
|
46904
|
+
await libsodium_wrappers_default.ready;
|
|
46905
|
+
const sodium = libsodium_wrappers_default;
|
|
46906
|
+
const privateKey = sodium.from_hex(privateKeyHex);
|
|
46907
|
+
const publicKey = privateKey.slice(32);
|
|
46908
|
+
const message = canonicalize(content);
|
|
46909
|
+
const signatureBytes = sodium.crypto_sign_detached(message, privateKey);
|
|
46910
|
+
return {
|
|
46911
|
+
content,
|
|
46912
|
+
signature: sodium.to_hex(signatureBytes),
|
|
46913
|
+
signerPublicKey: sodium.to_hex(publicKey),
|
|
46914
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46915
|
+
version: 1
|
|
46916
|
+
};
|
|
46917
|
+
}
|
|
46918
|
+
async function verifyApprovalArtifact(artifact, expectedPublicKeyHex) {
|
|
46919
|
+
await libsodium_wrappers_default.ready;
|
|
46920
|
+
const sodium = libsodium_wrappers_default;
|
|
46921
|
+
if (expectedPublicKeyHex && artifact.signerPublicKey !== expectedPublicKeyHex) {
|
|
46922
|
+
return false;
|
|
46923
|
+
}
|
|
46924
|
+
try {
|
|
46925
|
+
const publicKey = sodium.from_hex(artifact.signerPublicKey);
|
|
46926
|
+
const signature = sodium.from_hex(artifact.signature);
|
|
46927
|
+
const message = canonicalize(artifact.content);
|
|
46928
|
+
return sodium.crypto_sign_verify_detached(signature, message, publicKey);
|
|
46929
|
+
} catch {
|
|
46930
|
+
return false;
|
|
46931
|
+
}
|
|
46932
|
+
}
|
|
45991
46933
|
var init_approval = __esm({
|
|
45992
46934
|
async "../crypto/dist/approval.js"() {
|
|
45993
46935
|
"use strict";
|
|
46936
|
+
await init_libsodium_wrappers();
|
|
45994
46937
|
await init_did();
|
|
45995
46938
|
}
|
|
45996
46939
|
});
|
|
@@ -54937,7 +55880,7 @@ function byteSwap32(arr) {
|
|
|
54937
55880
|
}
|
|
54938
55881
|
return arr;
|
|
54939
55882
|
}
|
|
54940
|
-
function
|
|
55883
|
+
function bytesToHex4(bytes) {
|
|
54941
55884
|
abytes3(bytes);
|
|
54942
55885
|
if (hasHexBuiltin)
|
|
54943
55886
|
return bytes.toHex();
|
|
@@ -54956,7 +55899,7 @@ function asciiToBase16(ch) {
|
|
|
54956
55899
|
return ch - (asciis.a - 10);
|
|
54957
55900
|
return;
|
|
54958
55901
|
}
|
|
54959
|
-
function
|
|
55902
|
+
function hexToBytes4(hex3) {
|
|
54960
55903
|
if (typeof hex3 !== "string")
|
|
54961
55904
|
throw new Error("hex string expected, got " + typeof hex3);
|
|
54962
55905
|
if (hasHexBuiltin)
|
|
@@ -55252,7 +56195,7 @@ var init_u642 = __esm({
|
|
|
55252
56195
|
});
|
|
55253
56196
|
|
|
55254
56197
|
// ../../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha2.js
|
|
55255
|
-
var SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384,
|
|
56198
|
+
var SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842;
|
|
55256
56199
|
var init_sha22 = __esm({
|
|
55257
56200
|
"../../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha2.js"() {
|
|
55258
56201
|
init_md2();
|
|
@@ -55613,7 +56556,7 @@ var init_sha22 = __esm({
|
|
|
55613
56556
|
this.Hl = SHA384_IV2[15] | 0;
|
|
55614
56557
|
}
|
|
55615
56558
|
};
|
|
55616
|
-
|
|
56559
|
+
sha2563 = /* @__PURE__ */ createHasher2(() => new SHA256());
|
|
55617
56560
|
sha5122 = /* @__PURE__ */ createHasher2(() => new SHA512());
|
|
55618
56561
|
sha3842 = /* @__PURE__ */ createHasher2(() => new SHA384());
|
|
55619
56562
|
}
|
|
@@ -55649,14 +56592,14 @@ function hexToNumber3(hex3) {
|
|
|
55649
56592
|
return hex3 === "" ? _0n2 : BigInt("0x" + hex3);
|
|
55650
56593
|
}
|
|
55651
56594
|
function bytesToNumberBE(bytes) {
|
|
55652
|
-
return hexToNumber3(
|
|
56595
|
+
return hexToNumber3(bytesToHex4(bytes));
|
|
55653
56596
|
}
|
|
55654
56597
|
function bytesToNumberLE2(bytes) {
|
|
55655
56598
|
abytes3(bytes);
|
|
55656
|
-
return hexToNumber3(
|
|
56599
|
+
return hexToNumber3(bytesToHex4(Uint8Array.from(bytes).reverse()));
|
|
55657
56600
|
}
|
|
55658
56601
|
function numberToBytesBE2(n2, len) {
|
|
55659
|
-
return
|
|
56602
|
+
return hexToBytes4(n2.toString(16).padStart(len * 2, "0"));
|
|
55660
56603
|
}
|
|
55661
56604
|
function numberToBytesLE2(n2, len) {
|
|
55662
56605
|
return numberToBytesBE2(n2, len).reverse();
|
|
@@ -55665,7 +56608,7 @@ function ensureBytes(title, hex3, expectedLength) {
|
|
|
55665
56608
|
let res;
|
|
55666
56609
|
if (typeof hex3 === "string") {
|
|
55667
56610
|
try {
|
|
55668
|
-
res =
|
|
56611
|
+
res = hexToBytes4(hex3);
|
|
55669
56612
|
} catch (e) {
|
|
55670
56613
|
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
55671
56614
|
}
|
|
@@ -56693,7 +57636,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
56693
57636
|
return bytes;
|
|
56694
57637
|
}
|
|
56695
57638
|
toHex() {
|
|
56696
|
-
return
|
|
57639
|
+
return bytesToHex4(this.toBytes());
|
|
56697
57640
|
}
|
|
56698
57641
|
toString() {
|
|
56699
57642
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -56965,7 +57908,7 @@ var init_edwards = __esm({
|
|
|
56965
57908
|
return this.ep.toAffine(invertedZ);
|
|
56966
57909
|
}
|
|
56967
57910
|
toHex() {
|
|
56968
|
-
return
|
|
57911
|
+
return bytesToHex4(this.toBytes());
|
|
56969
57912
|
}
|
|
56970
57913
|
toString() {
|
|
56971
57914
|
return this.toHex();
|
|
@@ -58766,7 +59709,7 @@ function weierstrassN(params, extraOpts = {}) {
|
|
|
58766
59709
|
return encodePoint(Point, this, isCompressed);
|
|
58767
59710
|
}
|
|
58768
59711
|
toHex(isCompressed = true) {
|
|
58769
|
-
return
|
|
59712
|
+
return bytesToHex4(this.toBytes(isCompressed));
|
|
58770
59713
|
}
|
|
58771
59714
|
toString() {
|
|
58772
59715
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -59050,7 +59993,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59050
59993
|
return new Signature(Fn3.fromBytes(r2), Fn3.fromBytes(s2), recid);
|
|
59051
59994
|
}
|
|
59052
59995
|
static fromHex(hex3, format) {
|
|
59053
|
-
return this.fromBytes(
|
|
59996
|
+
return this.fromBytes(hexToBytes4(hex3), format);
|
|
59054
59997
|
}
|
|
59055
59998
|
addRecoveryBit(recovery) {
|
|
59056
59999
|
return new Signature(this.r, this.s, recovery);
|
|
@@ -59085,7 +60028,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59085
60028
|
toBytes(format = defaultSigOpts_format) {
|
|
59086
60029
|
validateSigFormat(format);
|
|
59087
60030
|
if (format === "der")
|
|
59088
|
-
return
|
|
60031
|
+
return hexToBytes4(DER.hexFromSig(this));
|
|
59089
60032
|
const r2 = Fn3.toBytes(this.r);
|
|
59090
60033
|
const s2 = Fn3.toBytes(this.s);
|
|
59091
60034
|
if (format === "recovered") {
|
|
@@ -59096,7 +60039,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59096
60039
|
return concatBytes2(r2, s2);
|
|
59097
60040
|
}
|
|
59098
60041
|
toHex(format) {
|
|
59099
|
-
return
|
|
60042
|
+
return bytesToHex4(this.toBytes(format));
|
|
59100
60043
|
}
|
|
59101
60044
|
// TODO: remove
|
|
59102
60045
|
assertValidity() {
|
|
@@ -59114,13 +60057,13 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59114
60057
|
return this.toBytes("der");
|
|
59115
60058
|
}
|
|
59116
60059
|
toDERHex() {
|
|
59117
|
-
return
|
|
60060
|
+
return bytesToHex4(this.toBytes("der"));
|
|
59118
60061
|
}
|
|
59119
60062
|
toCompactRawBytes() {
|
|
59120
60063
|
return this.toBytes("compact");
|
|
59121
60064
|
}
|
|
59122
60065
|
toCompactHex() {
|
|
59123
|
-
return
|
|
60066
|
+
return bytesToHex4(this.toBytes("compact"));
|
|
59124
60067
|
}
|
|
59125
60068
|
}
|
|
59126
60069
|
const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes) {
|
|
@@ -59499,7 +60442,7 @@ var init_nist = __esm({
|
|
|
59499
60442
|
Fp256 = Field(p256_CURVE.p);
|
|
59500
60443
|
Fp384 = Field(p384_CURVE.p);
|
|
59501
60444
|
Fp521 = Field(p521_CURVE.p);
|
|
59502
|
-
p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false },
|
|
60445
|
+
p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false }, sha2563);
|
|
59503
60446
|
p256_hasher = /* @__PURE__ */ (() => {
|
|
59504
60447
|
return createHasher3(p256.Point, createSWU(p256.Point, {
|
|
59505
60448
|
A: p256_CURVE.a,
|
|
@@ -59512,7 +60455,7 @@ var init_nist = __esm({
|
|
|
59512
60455
|
m: 1,
|
|
59513
60456
|
k: 128,
|
|
59514
60457
|
expand: "xmd",
|
|
59515
|
-
hash:
|
|
60458
|
+
hash: sha2563
|
|
59516
60459
|
});
|
|
59517
60460
|
})();
|
|
59518
60461
|
p384 = createCurve({ ...p384_CURVE, Fp: Fp384, lowS: false }, sha3842);
|
|
@@ -60020,7 +60963,7 @@ var init_u643 = __esm({
|
|
|
60020
60963
|
});
|
|
60021
60964
|
|
|
60022
60965
|
// ../crypto/node_modules/@noble/hashes/sha2.js
|
|
60023
|
-
var SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384,
|
|
60966
|
+
var SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384, sha2564, sha5123, sha3843;
|
|
60024
60967
|
var init_sha23 = __esm({
|
|
60025
60968
|
"../crypto/node_modules/@noble/hashes/sha2.js"() {
|
|
60026
60969
|
init_md3();
|
|
@@ -60393,7 +61336,7 @@ var init_sha23 = __esm({
|
|
|
60393
61336
|
super(48);
|
|
60394
61337
|
}
|
|
60395
61338
|
};
|
|
60396
|
-
|
|
61339
|
+
sha2564 = /* @__PURE__ */ createHasher4(
|
|
60397
61340
|
() => new _SHA256(),
|
|
60398
61341
|
/* @__PURE__ */ oidNist2(1)
|
|
60399
61342
|
);
|
|
@@ -60491,7 +61434,7 @@ function makeHashImpl2(h2) {
|
|
|
60491
61434
|
async digest(data) {
|
|
60492
61435
|
switch (h2) {
|
|
60493
61436
|
case "SHA-256":
|
|
60494
|
-
return
|
|
61437
|
+
return sha2564(data);
|
|
60495
61438
|
case "SHA-384":
|
|
60496
61439
|
return sha3843(data);
|
|
60497
61440
|
case "SHA-512":
|
|
@@ -60503,7 +61446,7 @@ function makeHashImpl2(h2) {
|
|
|
60503
61446
|
async mac(key, data) {
|
|
60504
61447
|
switch (h2) {
|
|
60505
61448
|
case "SHA-256":
|
|
60506
|
-
return hmac3(
|
|
61449
|
+
return hmac3(sha2564, key, data);
|
|
60507
61450
|
case "SHA-384":
|
|
60508
61451
|
return hmac3(sha3843, key, data);
|
|
60509
61452
|
case "SHA-512":
|
|
@@ -61670,6 +62613,92 @@ var init_mls_group = __esm({
|
|
|
61670
62613
|
});
|
|
61671
62614
|
|
|
61672
62615
|
// ../crypto/dist/index.js
|
|
62616
|
+
var dist_exports = {};
|
|
62617
|
+
__export(dist_exports, {
|
|
62618
|
+
AV_CREDENTIAL_CONTEXT: () => AV_CREDENTIAL_CONTEXT,
|
|
62619
|
+
CRYPTOSUITE: () => CRYPTOSUITE,
|
|
62620
|
+
DOMAIN_DID_DOCUMENT: () => DOMAIN_DID_DOCUMENT,
|
|
62621
|
+
DOMAIN_TRANSFER_ACCEPT: () => DOMAIN_TRANSFER_ACCEPT,
|
|
62622
|
+
DOMAIN_TRANSFER_INTENT: () => DOMAIN_TRANSFER_INTENT,
|
|
62623
|
+
DoubleRatchet: () => DoubleRatchet,
|
|
62624
|
+
MLSGroupManager: () => MLSGroupManager,
|
|
62625
|
+
ScanEngine: () => ScanEngine,
|
|
62626
|
+
TelemetryReporter: () => TelemetryReporter,
|
|
62627
|
+
VC_CONTEXT_V2: () => VC_CONTEXT_V2,
|
|
62628
|
+
base64ToBytes: () => base64ToBytes,
|
|
62629
|
+
buildA2aSpan: () => buildA2aSpan,
|
|
62630
|
+
buildActionSpan: () => buildActionSpan,
|
|
62631
|
+
buildAgentTrustCredential: () => buildAgentTrustCredential,
|
|
62632
|
+
buildAgentTrustReportCredential: () => buildAgentTrustReportCredential,
|
|
62633
|
+
buildCapabilitySpan: () => buildCapabilitySpan,
|
|
62634
|
+
buildDecisionSpan: () => buildDecisionSpan,
|
|
62635
|
+
buildDidDocument: () => buildDidDocument,
|
|
62636
|
+
buildEnrollmentSpan: () => buildEnrollmentSpan,
|
|
62637
|
+
buildErrorSpan: () => buildErrorSpan,
|
|
62638
|
+
buildEvalRunSpan: () => buildEvalRunSpan,
|
|
62639
|
+
buildEvalSpan: () => buildEvalSpan,
|
|
62640
|
+
buildForgeSpan: () => buildForgeSpan,
|
|
62641
|
+
buildHttpSpan: () => buildHttpSpan,
|
|
62642
|
+
buildLlmSpan: () => buildLlmSpan,
|
|
62643
|
+
buildNavSpan: () => buildNavSpan,
|
|
62644
|
+
buildPerformanceRecord: () => buildPerformanceRecord,
|
|
62645
|
+
buildPolicyViolationSpan: () => buildPolicyViolationSpan,
|
|
62646
|
+
buildResyncSpan: () => buildResyncSpan,
|
|
62647
|
+
buildRoomSpan: () => buildRoomSpan,
|
|
62648
|
+
buildScanSpan: () => buildScanSpan,
|
|
62649
|
+
buildSkillAttestation: () => buildSkillAttestation,
|
|
62650
|
+
buildSkillInvocationSpan: () => buildSkillInvocationSpan,
|
|
62651
|
+
buildTaskSpan: () => buildTaskSpan,
|
|
62652
|
+
buildToolSpan: () => buildToolSpan,
|
|
62653
|
+
buildTraceparent: () => buildTraceparent,
|
|
62654
|
+
buildTrustSpan: () => buildTrustSpan,
|
|
62655
|
+
buildVerifiablePresentation: () => buildVerifiablePresentation,
|
|
62656
|
+
buildWorkspaceSpan: () => buildWorkspaceSpan,
|
|
62657
|
+
bytesToBase64: () => bytesToBase64,
|
|
62658
|
+
bytesToHex: () => bytesToHex2,
|
|
62659
|
+
canonicalize: () => canonicalize,
|
|
62660
|
+
computeDidHash: () => computeDidHash,
|
|
62661
|
+
computeFileDigest: () => computeFileDigest,
|
|
62662
|
+
computeFingerprint: () => computeFingerprint,
|
|
62663
|
+
createApprovalArtifact: () => createApprovalArtifact,
|
|
62664
|
+
createProofOfPossession: () => createProofOfPossession,
|
|
62665
|
+
decryptBackup: () => decryptBackup,
|
|
62666
|
+
decryptFile: () => decryptFile,
|
|
62667
|
+
deriveBackupKey: () => deriveBackupKey,
|
|
62668
|
+
encryptBackup: () => encryptBackup,
|
|
62669
|
+
encryptBackupWithKey: () => encryptBackupWithKey,
|
|
62670
|
+
encryptFile: () => encryptFile,
|
|
62671
|
+
encryptedMessageToHexTransport: () => encryptedMessageToHexTransport,
|
|
62672
|
+
encryptedMessageToTransport: () => encryptedMessageToTransport,
|
|
62673
|
+
encryptedMessageToTransportV2: () => encryptedMessageToTransportV2,
|
|
62674
|
+
encryptedMessageToTransportV2Full: () => encryptedMessageToTransportV2Full,
|
|
62675
|
+
formatBackupCode: () => formatBackupCode,
|
|
62676
|
+
generateBackupCode: () => generateBackupCode,
|
|
62677
|
+
generateEphemeralKeypair: () => generateEphemeralKeypair,
|
|
62678
|
+
generateIdentityKeypair: () => generateIdentityKeypair,
|
|
62679
|
+
hashBackupCode: () => hashBackupCode,
|
|
62680
|
+
hexToBytes: () => hexToBytes2,
|
|
62681
|
+
hexTransportToEncryptedMessage: () => hexTransportToEncryptedMessage,
|
|
62682
|
+
issueCredential: () => issueCredential,
|
|
62683
|
+
multibaseToPublicKey: () => multibaseToPublicKey,
|
|
62684
|
+
normalizeBackupCode: () => normalizeBackupCode,
|
|
62685
|
+
parseTraceparent: () => parseTraceparent,
|
|
62686
|
+
performX3DH: () => performX3DH,
|
|
62687
|
+
presentCredentials: () => presentCredentials,
|
|
62688
|
+
propagateContext: () => propagateContext,
|
|
62689
|
+
publicKeyToMultibase: () => publicKeyToMultibase,
|
|
62690
|
+
signDocument: () => signDocument,
|
|
62691
|
+
signWithDataIntegrity: () => signWithDataIntegrity,
|
|
62692
|
+
spanToTraceContext: () => spanToTraceContext,
|
|
62693
|
+
spanToW3CHeaders: () => spanToW3CHeaders,
|
|
62694
|
+
transportToEncryptedMessage: () => transportToEncryptedMessage,
|
|
62695
|
+
transportV2ToEncryptedMessage: () => transportV2ToEncryptedMessage,
|
|
62696
|
+
verifyApprovalArtifact: () => verifyApprovalArtifact,
|
|
62697
|
+
verifyDataIntegrity: () => verifyDataIntegrity,
|
|
62698
|
+
verifyDocumentSignature: () => verifyDocumentSignature,
|
|
62699
|
+
verifyMerkleProof: () => verifyMerkleProof,
|
|
62700
|
+
verifyProofOfPossession: () => verifyProofOfPossession
|
|
62701
|
+
});
|
|
61673
62702
|
var init_dist = __esm({
|
|
61674
62703
|
async "../crypto/dist/index.js"() {
|
|
61675
62704
|
"use strict";
|
|
@@ -61960,7 +62989,7 @@ async function uploadBackupToServer(state, backupCode, apiUrl, deviceJwt) {
|
|
|
61960
62989
|
},
|
|
61961
62990
|
body: JSON.stringify({
|
|
61962
62991
|
backup_blob: bytesToBase64(encrypted),
|
|
61963
|
-
backup_code_hash:
|
|
62992
|
+
backup_code_hash: bytesToHex2(codeHash)
|
|
61964
62993
|
})
|
|
61965
62994
|
});
|
|
61966
62995
|
if (!resp.ok) {
|
|
@@ -62604,6 +63633,8 @@ var init_channel = __esm({
|
|
|
62604
63633
|
_mlsGroups = /* @__PURE__ */ new Map();
|
|
62605
63634
|
/** Cached MLS KeyPackage bundle for this device (regenerated on each connect). */
|
|
62606
63635
|
_mlsKeyPackage = null;
|
|
63636
|
+
/** Pending KeyPackage bundle from request-Welcome flow (used by _handleMlsWelcome). */
|
|
63637
|
+
_pendingMlsKpBundle;
|
|
62607
63638
|
/** In-memory credential store for renter-provided credentials (never persisted). */
|
|
62608
63639
|
_credentialStore = new CredentialStore();
|
|
62609
63640
|
/** Dedup buffer for A2A message IDs (prevents double-delivery via direct + Redis) */
|
|
@@ -62702,6 +63733,24 @@ var init_channel = __esm({
|
|
|
62702
63733
|
if (this._persisted.seenA2AMessageIds) {
|
|
62703
63734
|
this._a2aSeenMessageIds = new Set(this._persisted.seenA2AMessageIds.slice(-_SecureChannel.A2A_SEEN_MAX));
|
|
62704
63735
|
}
|
|
63736
|
+
if (this._persisted?.rooms) {
|
|
63737
|
+
const roomConvIds = /* @__PURE__ */ new Set();
|
|
63738
|
+
for (const room of Object.values(this._persisted.rooms)) {
|
|
63739
|
+
for (const cid of room.conversationIds || []) {
|
|
63740
|
+
roomConvIds.add(cid);
|
|
63741
|
+
}
|
|
63742
|
+
}
|
|
63743
|
+
let cleanedCount = 0;
|
|
63744
|
+
for (const cid of roomConvIds) {
|
|
63745
|
+
if (this._persisted.sessions[cid]) {
|
|
63746
|
+
delete this._persisted.sessions[cid];
|
|
63747
|
+
cleanedCount++;
|
|
63748
|
+
}
|
|
63749
|
+
}
|
|
63750
|
+
if (cleanedCount > 0) {
|
|
63751
|
+
console.log(`[SecureChannel] Cleaned ${cleanedCount} stale DR room sessions`);
|
|
63752
|
+
}
|
|
63753
|
+
}
|
|
62705
63754
|
for (const [convId, sessionData] of Object.entries(
|
|
62706
63755
|
this._persisted.sessions
|
|
62707
63756
|
)) {
|
|
@@ -63074,89 +64123,21 @@ var init_channel = __esm({
|
|
|
63074
64123
|
}
|
|
63075
64124
|
// --- Multi-agent room methods ---
|
|
63076
64125
|
/**
|
|
63077
|
-
* Join a room by
|
|
63078
|
-
*
|
|
64126
|
+
* Join a room by collecting pairwise conversation IDs involving this device.
|
|
64127
|
+
* Encryption is handled by MLS group operations, not per-member DR sessions.
|
|
63079
64128
|
*/
|
|
63080
64129
|
async joinRoom(roomData) {
|
|
63081
64130
|
if (!this._persisted) {
|
|
63082
64131
|
throw new Error("Channel not initialized");
|
|
63083
64132
|
}
|
|
63084
64133
|
await libsodium_wrappers_default.ready;
|
|
63085
|
-
if (roomData.forceRekey) {
|
|
63086
|
-
let cleared = 0;
|
|
63087
|
-
const existingRoom = this._persisted.rooms?.[roomData.roomId];
|
|
63088
|
-
if (existingRoom) {
|
|
63089
|
-
for (const convId of existingRoom.conversationIds) {
|
|
63090
|
-
if (this._sessions.has(convId)) {
|
|
63091
|
-
this._sessions.delete(convId);
|
|
63092
|
-
cleared++;
|
|
63093
|
-
}
|
|
63094
|
-
delete this._persisted.sessions[convId];
|
|
63095
|
-
}
|
|
63096
|
-
}
|
|
63097
|
-
if (this._persisted) {
|
|
63098
|
-
this._persisted.lastMessageTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
63099
|
-
}
|
|
63100
|
-
console.log(
|
|
63101
|
-
`[SecureChannel] Force rekey: cleared ${cleared} sessions for room ${roomData.roomId.slice(0, 8)}...`
|
|
63102
|
-
);
|
|
63103
|
-
}
|
|
63104
|
-
const identity = this._persisted.identityKeypair;
|
|
63105
|
-
const ephemeral = this._persisted.ephemeralKeypair;
|
|
63106
64134
|
const myDeviceId = this._deviceId;
|
|
63107
64135
|
const conversationIds = [];
|
|
63108
64136
|
for (const conv of roomData.conversations) {
|
|
63109
64137
|
if (conv.participantA !== myDeviceId && conv.participantB !== myDeviceId) {
|
|
63110
64138
|
continue;
|
|
63111
64139
|
}
|
|
63112
|
-
if (this._sessions.has(conv.id)) {
|
|
63113
|
-
conversationIds.push(conv.id);
|
|
63114
|
-
continue;
|
|
63115
|
-
}
|
|
63116
|
-
const otherDeviceId = conv.participantA === myDeviceId ? conv.participantB : conv.participantA;
|
|
63117
|
-
const otherMember = roomData.members.find((m2) => m2.deviceId === otherDeviceId);
|
|
63118
|
-
if (!otherMember?.identityPublicKey) {
|
|
63119
|
-
console.warn(
|
|
63120
|
-
`[SecureChannel] No public key for member ${otherDeviceId.slice(0, 8)}..., skipping`
|
|
63121
|
-
);
|
|
63122
|
-
continue;
|
|
63123
|
-
}
|
|
63124
|
-
const isInitiator = myDeviceId < otherDeviceId;
|
|
63125
|
-
const theirEphKey = otherMember.ephemeralPublicKey ?? otherMember.identityPublicKey;
|
|
63126
|
-
const sharedSecret = performX3DH({
|
|
63127
|
-
myIdentityPrivate: hexToBytes(identity.privateKey),
|
|
63128
|
-
myEphemeralPrivate: hexToBytes(ephemeral.privateKey),
|
|
63129
|
-
theirIdentityPublic: hexToBytes(otherMember.identityPublicKey),
|
|
63130
|
-
theirEphemeralPublic: hexToBytes(theirEphKey),
|
|
63131
|
-
isInitiator
|
|
63132
|
-
});
|
|
63133
|
-
const peerIdentityPub = hexToBytes(otherMember.identityPublicKey);
|
|
63134
|
-
const ratchet = isInitiator ? DoubleRatchet.initSender(sharedSecret, {
|
|
63135
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
63136
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
63137
|
-
keyType: "ed25519"
|
|
63138
|
-
}, peerIdentityPub) : DoubleRatchet.initReceiver(sharedSecret, {
|
|
63139
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
63140
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
63141
|
-
keyType: "ed25519"
|
|
63142
|
-
}, peerIdentityPub);
|
|
63143
|
-
this._sessions.set(conv.id, {
|
|
63144
|
-
ownerDeviceId: otherDeviceId,
|
|
63145
|
-
ratchet,
|
|
63146
|
-
activated: isInitiator,
|
|
63147
|
-
// initiator can send immediately
|
|
63148
|
-
epoch: 1
|
|
63149
|
-
});
|
|
63150
|
-
this._persisted.sessions[conv.id] = {
|
|
63151
|
-
ownerDeviceId: otherDeviceId,
|
|
63152
|
-
ratchetState: ratchet.serialize(),
|
|
63153
|
-
activated: isInitiator,
|
|
63154
|
-
epoch: 1
|
|
63155
|
-
};
|
|
63156
64140
|
conversationIds.push(conv.id);
|
|
63157
|
-
console.log(
|
|
63158
|
-
`[SecureChannel] Room session initialized: conv ${conv.id.slice(0, 8)}... with ${otherDeviceId.slice(0, 8)}... (initiator=${isInitiator})`
|
|
63159
|
-
);
|
|
63160
64141
|
}
|
|
63161
64142
|
if (!this._persisted.rooms) {
|
|
63162
64143
|
this._persisted.rooms = {};
|
|
@@ -63252,68 +64233,15 @@ var init_channel = __esm({
|
|
|
63252
64233
|
}
|
|
63253
64234
|
return;
|
|
63254
64235
|
} catch (mlsErr) {
|
|
63255
|
-
|
|
63256
|
-
|
|
63257
|
-
|
|
63258
|
-
}
|
|
63259
|
-
const recipients = [];
|
|
63260
|
-
for (const convId of room.conversationIds) {
|
|
63261
|
-
const session = this._sessions.get(convId);
|
|
63262
|
-
if (!session) {
|
|
63263
|
-
console.warn(`[SecureChannel] No session for room conv ${convId.slice(0, 8)}..., skipping`);
|
|
63264
|
-
continue;
|
|
63265
|
-
}
|
|
63266
|
-
const encrypted = session.ratchet.encrypt(plaintext);
|
|
63267
|
-
const transport = encryptedMessageToTransport(encrypted);
|
|
63268
|
-
recipients.push({
|
|
63269
|
-
device_id: session.ownerDeviceId,
|
|
63270
|
-
header_blob: transport.header_blob,
|
|
63271
|
-
ciphertext: transport.ciphertext
|
|
63272
|
-
});
|
|
63273
|
-
}
|
|
63274
|
-
if (recipients.length === 0) {
|
|
63275
|
-
throw new Error("No active sessions in room");
|
|
63276
|
-
}
|
|
63277
|
-
await this._persistState();
|
|
63278
|
-
if (this._state === "ready" && this._ws) {
|
|
63279
|
-
this._ws.send(
|
|
63280
|
-
JSON.stringify({
|
|
63281
|
-
event: "room_message",
|
|
63282
|
-
data: {
|
|
63283
|
-
room_id: roomId,
|
|
63284
|
-
recipients,
|
|
63285
|
-
message_type: messageType,
|
|
63286
|
-
priority: opts?.priority ?? "normal",
|
|
63287
|
-
metadata: opts?.metadata
|
|
63288
|
-
}
|
|
63289
|
-
})
|
|
63290
|
-
);
|
|
63291
|
-
} else {
|
|
63292
|
-
try {
|
|
63293
|
-
const res = await fetch(
|
|
63294
|
-
`${this.config.apiUrl}/api/v1/rooms/${roomId}/messages`,
|
|
63295
|
-
{
|
|
63296
|
-
method: "POST",
|
|
63297
|
-
headers: {
|
|
63298
|
-
"Content-Type": "application/json",
|
|
63299
|
-
Authorization: `Bearer ${this._deviceJwt}`
|
|
63300
|
-
},
|
|
63301
|
-
body: JSON.stringify({
|
|
63302
|
-
recipients,
|
|
63303
|
-
message_type: messageType,
|
|
63304
|
-
priority: opts?.priority ?? "normal",
|
|
63305
|
-
metadata: opts?.metadata
|
|
63306
|
-
})
|
|
63307
|
-
}
|
|
63308
|
-
);
|
|
63309
|
-
if (!res.ok) {
|
|
63310
|
-
const detail = await res.text();
|
|
63311
|
-
throw new Error(`Room message failed (${res.status}): ${detail}`);
|
|
64236
|
+
throw new Error(
|
|
64237
|
+
`MLS encrypt failed for room ${roomId.slice(0, 8)}... \u2014 MLS group must be initialized before sending. Error: ${mlsErr}`
|
|
64238
|
+
);
|
|
63312
64239
|
}
|
|
63313
|
-
} catch (err) {
|
|
63314
|
-
throw new Error(`Failed to send room message: ${err}`);
|
|
63315
64240
|
}
|
|
63316
64241
|
}
|
|
64242
|
+
throw new Error(
|
|
64243
|
+
`Room ${roomId.slice(0, 8)}... has no initialized MLS group. MLS initialization must complete before messages can be sent.`
|
|
64244
|
+
);
|
|
63317
64245
|
}
|
|
63318
64246
|
/**
|
|
63319
64247
|
* Leave a room: remove sessions and persisted room state.
|
|
@@ -64143,9 +65071,9 @@ var init_channel = __esm({
|
|
|
64143
65071
|
const result = await enrollDevice(
|
|
64144
65072
|
this.config.apiUrl,
|
|
64145
65073
|
this.config.inviteToken,
|
|
64146
|
-
|
|
64147
|
-
|
|
64148
|
-
|
|
65074
|
+
bytesToHex2(identity.publicKey),
|
|
65075
|
+
bytesToHex2(ephemeral.publicKey),
|
|
65076
|
+
bytesToHex2(proof),
|
|
64149
65077
|
this.config.platform
|
|
64150
65078
|
);
|
|
64151
65079
|
this._deviceId = result.device_id;
|
|
@@ -64159,12 +65087,12 @@ var init_channel = __esm({
|
|
|
64159
65087
|
sessions: {},
|
|
64160
65088
|
// populated after activation
|
|
64161
65089
|
identityKeypair: {
|
|
64162
|
-
publicKey:
|
|
64163
|
-
privateKey:
|
|
65090
|
+
publicKey: bytesToHex2(identity.publicKey),
|
|
65091
|
+
privateKey: bytesToHex2(identity.privateKey)
|
|
64164
65092
|
},
|
|
64165
65093
|
ephemeralKeypair: {
|
|
64166
|
-
publicKey:
|
|
64167
|
-
privateKey:
|
|
65094
|
+
publicKey: bytesToHex2(ephemeral.publicKey),
|
|
65095
|
+
privateKey: bytesToHex2(ephemeral.privateKey)
|
|
64168
65096
|
},
|
|
64169
65097
|
fingerprint: result.fingerprint,
|
|
64170
65098
|
messageHistory: []
|
|
@@ -64227,17 +65155,17 @@ var init_channel = __esm({
|
|
|
64227
65155
|
const ownerIdentityKey = conv.owner_identity_public_key || result.owner_identity_public_key;
|
|
64228
65156
|
const ownerEphemeralKey = conv.owner_ephemeral_public_key || result.owner_ephemeral_public_key || ownerIdentityKey;
|
|
64229
65157
|
const sharedSecret = performX3DH({
|
|
64230
|
-
myIdentityPrivate:
|
|
64231
|
-
myEphemeralPrivate:
|
|
64232
|
-
theirIdentityPublic:
|
|
64233
|
-
theirEphemeralPublic:
|
|
65158
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
65159
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
65160
|
+
theirIdentityPublic: hexToBytes2(ownerIdentityKey),
|
|
65161
|
+
theirEphemeralPublic: hexToBytes2(ownerEphemeralKey),
|
|
64234
65162
|
isInitiator: false
|
|
64235
65163
|
});
|
|
64236
65164
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
64237
|
-
publicKey:
|
|
64238
|
-
privateKey:
|
|
65165
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
65166
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
64239
65167
|
keyType: "ed25519"
|
|
64240
|
-
},
|
|
65168
|
+
}, hexToBytes2(ownerIdentityKey));
|
|
64241
65169
|
this._sessions.set(conv.conversation_id, {
|
|
64242
65170
|
ownerDeviceId: conv.owner_device_id,
|
|
64243
65171
|
ratchet,
|
|
@@ -65363,19 +66291,19 @@ ${messageText}`;
|
|
|
65363
66291
|
const identity = this._persisted.identityKeypair;
|
|
65364
66292
|
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65365
66293
|
const sharedSecret = performX3DH({
|
|
65366
|
-
myIdentityPrivate:
|
|
65367
|
-
myEphemeralPrivate:
|
|
65368
|
-
theirIdentityPublic:
|
|
65369
|
-
theirEphemeralPublic:
|
|
66294
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
66295
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
66296
|
+
theirIdentityPublic: hexToBytes2(event.owner_identity_public_key),
|
|
66297
|
+
theirEphemeralPublic: hexToBytes2(
|
|
65370
66298
|
event.owner_ephemeral_public_key ?? event.owner_identity_public_key
|
|
65371
66299
|
),
|
|
65372
66300
|
isInitiator: false
|
|
65373
66301
|
});
|
|
65374
66302
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
65375
|
-
publicKey:
|
|
65376
|
-
privateKey:
|
|
66303
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
66304
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
65377
66305
|
keyType: "ed25519"
|
|
65378
|
-
},
|
|
66306
|
+
}, hexToBytes2(event.owner_identity_public_key));
|
|
65379
66307
|
this._sessions.set(event.conversation_id, {
|
|
65380
66308
|
ownerDeviceId: event.owner_device_id,
|
|
65381
66309
|
ratchet,
|
|
@@ -65422,17 +66350,17 @@ ${messageText}`;
|
|
|
65422
66350
|
const identity = this._persisted.identityKeypair;
|
|
65423
66351
|
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65424
66352
|
const sharedSecret = performX3DH({
|
|
65425
|
-
myIdentityPrivate:
|
|
65426
|
-
myEphemeralPrivate:
|
|
65427
|
-
theirIdentityPublic:
|
|
65428
|
-
theirEphemeralPublic:
|
|
66353
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
66354
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
66355
|
+
theirIdentityPublic: hexToBytes2(data.identity_public_key),
|
|
66356
|
+
theirEphemeralPublic: hexToBytes2(data.ephemeral_public_key),
|
|
65429
66357
|
isInitiator: false
|
|
65430
66358
|
});
|
|
65431
66359
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
65432
|
-
publicKey:
|
|
65433
|
-
privateKey:
|
|
66360
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
66361
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
65434
66362
|
keyType: "ed25519"
|
|
65435
|
-
},
|
|
66363
|
+
}, hexToBytes2(data.identity_public_key));
|
|
65436
66364
|
const existingSession = this._sessions.get(convId);
|
|
65437
66365
|
const existingPersisted = this._persisted.sessions[convId];
|
|
65438
66366
|
const ownerDeviceId = data.sender_device_id ?? existingSession?.ownerDeviceId ?? "";
|
|
@@ -65473,250 +66401,8 @@ ${messageText}`;
|
|
|
65473
66401
|
this.emit("error", err);
|
|
65474
66402
|
}
|
|
65475
66403
|
}
|
|
65476
|
-
|
|
65477
|
-
|
|
65478
|
-
* Shared by all room ratchet failure paths to avoid code duplication.
|
|
65479
|
-
*/
|
|
65480
|
-
_sendRoomResyncIfCooled(convId, reason, session) {
|
|
65481
|
-
const RESYNC_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
65482
|
-
const lastResync = this._lastResyncRequest.get(convId) ?? 0;
|
|
65483
|
-
if (Date.now() - lastResync > RESYNC_COOLDOWN_MS && this._ws && this._persisted) {
|
|
65484
|
-
this._lastResyncRequest.set(convId, Date.now());
|
|
65485
|
-
this._ws.send(
|
|
65486
|
-
JSON.stringify({
|
|
65487
|
-
event: "resync_request",
|
|
65488
|
-
data: {
|
|
65489
|
-
conversation_id: convId,
|
|
65490
|
-
reason,
|
|
65491
|
-
identity_public_key: this._persisted.identityKeypair.publicKey,
|
|
65492
|
-
ephemeral_public_key: this._persisted.ephemeralKeypair.publicKey,
|
|
65493
|
-
epoch: session?.epoch
|
|
65494
|
-
}
|
|
65495
|
-
})
|
|
65496
|
-
);
|
|
65497
|
-
console.log(
|
|
65498
|
-
`[SecureChannel] Room resync requested for conv ${convId.slice(0, 8)} (${reason})`
|
|
65499
|
-
);
|
|
65500
|
-
}
|
|
65501
|
-
}
|
|
65502
|
-
/**
|
|
65503
|
-
* Handle an incoming room message (pairwise path — used by sync replay and pairwise room fallback).
|
|
65504
|
-
* Finds the pairwise conversation for the sender, decrypts, and emits a room_message event.
|
|
65505
|
-
*/
|
|
65506
|
-
async _handleRoomMessage(msgData) {
|
|
65507
|
-
if (msgData.sender_device_id === this._deviceId) return;
|
|
65508
|
-
this._lastInboundRoomId = msgData.room_id;
|
|
65509
|
-
const convId = msgData.conversation_id ?? this._findConversationForSender(msgData.sender_device_id, msgData.room_id);
|
|
65510
|
-
if (!convId) {
|
|
65511
|
-
console.warn(
|
|
65512
|
-
`[SecureChannel] No conversation found for sender ${msgData.sender_device_id.slice(0, 8)}... in room ${msgData.room_id}`
|
|
65513
|
-
);
|
|
65514
|
-
return;
|
|
65515
|
-
}
|
|
65516
|
-
let session = this._sessions.get(convId);
|
|
65517
|
-
if (!session) {
|
|
65518
|
-
console.warn(
|
|
65519
|
-
`[SecureChannel] No session for room conv ${convId.slice(0, 8)}..., fetching room data`
|
|
65520
|
-
);
|
|
65521
|
-
try {
|
|
65522
|
-
const roomRes = await fetch(
|
|
65523
|
-
`${this.config.apiUrl}/api/v1/rooms/${msgData.room_id}`,
|
|
65524
|
-
{
|
|
65525
|
-
headers: {
|
|
65526
|
-
Authorization: `Bearer ${this._persisted.deviceJwt}`
|
|
65527
|
-
}
|
|
65528
|
-
}
|
|
65529
|
-
);
|
|
65530
|
-
if (roomRes.ok) {
|
|
65531
|
-
const roomData = await roomRes.json();
|
|
65532
|
-
await this.joinRoom({
|
|
65533
|
-
roomId: roomData.id,
|
|
65534
|
-
name: roomData.name,
|
|
65535
|
-
members: (roomData.members || []).map((m2) => ({
|
|
65536
|
-
deviceId: m2.device_id,
|
|
65537
|
-
entityType: m2.entity_type,
|
|
65538
|
-
displayName: m2.display_name,
|
|
65539
|
-
identityPublicKey: m2.identity_public_key,
|
|
65540
|
-
ephemeralPublicKey: m2.ephemeral_public_key
|
|
65541
|
-
})),
|
|
65542
|
-
conversations: (roomData.conversations || []).map((c2) => ({
|
|
65543
|
-
id: c2.id,
|
|
65544
|
-
participantA: c2.participant_a,
|
|
65545
|
-
participantB: c2.participant_b
|
|
65546
|
-
}))
|
|
65547
|
-
});
|
|
65548
|
-
session = this._sessions.get(convId);
|
|
65549
|
-
}
|
|
65550
|
-
} catch (fetchErr) {
|
|
65551
|
-
console.error(
|
|
65552
|
-
`[SecureChannel] Failed to fetch room data for ${msgData.room_id}:`,
|
|
65553
|
-
fetchErr
|
|
65554
|
-
);
|
|
65555
|
-
}
|
|
65556
|
-
if (!session) {
|
|
65557
|
-
console.warn(
|
|
65558
|
-
`[SecureChannel] Still no session for room conv ${convId.slice(0, 8)}... after refresh, skipping`
|
|
65559
|
-
);
|
|
65560
|
-
return;
|
|
65561
|
-
}
|
|
65562
|
-
}
|
|
65563
|
-
const encrypted = transportToEncryptedMessage({
|
|
65564
|
-
header_blob: msgData.header_blob,
|
|
65565
|
-
ciphertext: msgData.ciphertext
|
|
65566
|
-
});
|
|
65567
|
-
let plaintext;
|
|
65568
|
-
const ratchetSnapshot = session.ratchet.serialize();
|
|
65569
|
-
try {
|
|
65570
|
-
plaintext = session.ratchet.decrypt(encrypted);
|
|
65571
|
-
} catch (decryptErr) {
|
|
65572
|
-
try {
|
|
65573
|
-
session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
|
|
65574
|
-
} catch {
|
|
65575
|
-
}
|
|
65576
|
-
console.warn(
|
|
65577
|
-
`[SecureChannel] Room decrypt failed for conv ${convId.slice(0, 8)}...: ${String(decryptErr)}, re-initializing ratchet`
|
|
65578
|
-
);
|
|
65579
|
-
try {
|
|
65580
|
-
const roomEntry = this._persisted?.rooms ? Object.values(this._persisted.rooms).find(
|
|
65581
|
-
(r2) => r2.conversationIds.includes(convId)
|
|
65582
|
-
) : null;
|
|
65583
|
-
if (!roomEntry) throw new Error("Room not found for conversation");
|
|
65584
|
-
const otherMember = roomEntry.members.find(
|
|
65585
|
-
(m2) => m2.deviceId === msgData.sender_device_id
|
|
65586
|
-
);
|
|
65587
|
-
if (!otherMember?.identityPublicKey) throw new Error("No key for sender");
|
|
65588
|
-
const isInitiator = this._deviceId < msgData.sender_device_id;
|
|
65589
|
-
const identity = this._persisted.identityKeypair;
|
|
65590
|
-
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65591
|
-
const sharedSecret = performX3DH({
|
|
65592
|
-
myIdentityPrivate: hexToBytes(identity.privateKey),
|
|
65593
|
-
myEphemeralPrivate: hexToBytes(ephemeral.privateKey),
|
|
65594
|
-
theirIdentityPublic: hexToBytes(otherMember.identityPublicKey),
|
|
65595
|
-
theirEphemeralPublic: hexToBytes(
|
|
65596
|
-
otherMember.ephemeralPublicKey ?? otherMember.identityPublicKey
|
|
65597
|
-
),
|
|
65598
|
-
isInitiator
|
|
65599
|
-
});
|
|
65600
|
-
const peerIdPub = hexToBytes(otherMember.identityPublicKey);
|
|
65601
|
-
const newRatchet = isInitiator ? DoubleRatchet.initSender(sharedSecret, {
|
|
65602
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
65603
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
65604
|
-
keyType: "ed25519"
|
|
65605
|
-
}, peerIdPub) : DoubleRatchet.initReceiver(sharedSecret, {
|
|
65606
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
65607
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
65608
|
-
keyType: "ed25519"
|
|
65609
|
-
}, peerIdPub);
|
|
65610
|
-
session.ratchet = newRatchet;
|
|
65611
|
-
session.activated = false;
|
|
65612
|
-
this._persisted.sessions[convId] = {
|
|
65613
|
-
ownerDeviceId: session.ownerDeviceId,
|
|
65614
|
-
ratchetState: newRatchet.serialize(),
|
|
65615
|
-
activated: false
|
|
65616
|
-
};
|
|
65617
|
-
await this._persistState();
|
|
65618
|
-
console.log(
|
|
65619
|
-
`[SecureChannel] Room ratchet re-initialized for conv ${convId.slice(0, 8)}...`
|
|
65620
|
-
);
|
|
65621
|
-
const incomingMsgNum = encrypted.header.messageNumber;
|
|
65622
|
-
if (incomingMsgNum <= 5) {
|
|
65623
|
-
try {
|
|
65624
|
-
plaintext = session.ratchet.decrypt(encrypted);
|
|
65625
|
-
session.activated = true;
|
|
65626
|
-
if (this._persisted.sessions[convId]) {
|
|
65627
|
-
this._persisted.sessions[convId].activated = true;
|
|
65628
|
-
}
|
|
65629
|
-
await this._persistState();
|
|
65630
|
-
console.log(
|
|
65631
|
-
`[SecureChannel] Room session ${convId.slice(0, 8)}... re-activated after ratchet re-init`
|
|
65632
|
-
);
|
|
65633
|
-
} catch (retryErr) {
|
|
65634
|
-
console.warn(
|
|
65635
|
-
`[SecureChannel] Room re-init retry failed for conv ${convId.slice(0, 8)} (msgNum=${incomingMsgNum}):`,
|
|
65636
|
-
retryErr
|
|
65637
|
-
);
|
|
65638
|
-
this._sendRoomResyncIfCooled(convId, "room_reinit_retry_failed", session);
|
|
65639
|
-
return;
|
|
65640
|
-
}
|
|
65641
|
-
} else {
|
|
65642
|
-
console.log(
|
|
65643
|
-
`[SecureChannel] Room re-init: skipping message with msgNum=${incomingMsgNum} for conv ${convId.slice(0, 8)} (too far ahead for fresh ratchet)`
|
|
65644
|
-
);
|
|
65645
|
-
this._sendRoomResyncIfCooled(convId, "room_message_skip");
|
|
65646
|
-
return;
|
|
65647
|
-
}
|
|
65648
|
-
} catch (reinitErr) {
|
|
65649
|
-
console.error(
|
|
65650
|
-
`[SecureChannel] Room ratchet re-init failed for conv ${convId.slice(0, 8)}...:`,
|
|
65651
|
-
reinitErr
|
|
65652
|
-
);
|
|
65653
|
-
this._sendRoomResyncIfCooled(convId, "room_reinit_failed");
|
|
65654
|
-
return;
|
|
65655
|
-
}
|
|
65656
|
-
}
|
|
65657
|
-
let messageText;
|
|
65658
|
-
let messageType;
|
|
65659
|
-
try {
|
|
65660
|
-
const parsed = JSON.parse(plaintext);
|
|
65661
|
-
messageType = parsed.type || "message";
|
|
65662
|
-
messageText = parsed.text || plaintext;
|
|
65663
|
-
} catch {
|
|
65664
|
-
messageType = "message";
|
|
65665
|
-
messageText = plaintext;
|
|
65666
|
-
}
|
|
65667
|
-
if (CREDENTIAL_MESSAGE_TYPES.has(messageType)) {
|
|
65668
|
-
this._handleCredentialMessage(msgData.room_id, messageType, messageText, msgData.message_id);
|
|
65669
|
-
if (msgData.created_at && this._persisted) {
|
|
65670
|
-
this._persisted.lastMessageTimestamp = msgData.created_at;
|
|
65671
|
-
}
|
|
65672
|
-
await this._persistState();
|
|
65673
|
-
return;
|
|
65674
|
-
}
|
|
65675
|
-
if (!ROOM_AGENT_TYPES.has(messageType)) {
|
|
65676
|
-
return;
|
|
65677
|
-
}
|
|
65678
|
-
if (!session.activated) {
|
|
65679
|
-
session.activated = true;
|
|
65680
|
-
console.log(
|
|
65681
|
-
`[SecureChannel] Room session ${convId.slice(0, 8)}... activated by first message`
|
|
65682
|
-
);
|
|
65683
|
-
}
|
|
65684
|
-
if (msgData.message_id) {
|
|
65685
|
-
this._sendAck(msgData.message_id);
|
|
65686
|
-
}
|
|
65687
|
-
if (msgData.created_at && this._persisted) {
|
|
65688
|
-
this._persisted.lastMessageTimestamp = msgData.created_at;
|
|
65689
|
-
}
|
|
65690
|
-
await this._persistState();
|
|
65691
|
-
const legacyRoomMembers = this._persisted?.rooms?.[msgData.room_id]?.members ?? [];
|
|
65692
|
-
const legacySenderMember = legacyRoomMembers.find((m2) => m2.deviceId === msgData.sender_device_id);
|
|
65693
|
-
const legacySenderIsAgent = legacySenderMember?.entityType === "agent";
|
|
65694
|
-
const legacySenderLabel = legacySenderMember?.displayName || "someone";
|
|
65695
|
-
const metadata = {
|
|
65696
|
-
messageId: msgData.message_id ?? "",
|
|
65697
|
-
conversationId: convId,
|
|
65698
|
-
timestamp: msgData.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
65699
|
-
messageType,
|
|
65700
|
-
roomId: msgData.room_id,
|
|
65701
|
-
senderDeviceId: msgData.sender_device_id,
|
|
65702
|
-
senderIsAgent: legacySenderIsAgent,
|
|
65703
|
-
senderName: legacySenderLabel,
|
|
65704
|
-
roomName: this._persisted?.rooms?.[msgData.room_id]?.name
|
|
65705
|
-
};
|
|
65706
|
-
this._appendHistory("owner", messageText, `room:${msgData.room_id}`);
|
|
65707
|
-
this.emit("room_message", {
|
|
65708
|
-
roomId: msgData.room_id,
|
|
65709
|
-
senderDeviceId: msgData.sender_device_id,
|
|
65710
|
-
senderName: legacySenderLabel,
|
|
65711
|
-
plaintext: messageText,
|
|
65712
|
-
messageType,
|
|
65713
|
-
timestamp: msgData.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
65714
|
-
});
|
|
65715
|
-
const legacyContextualMessage = legacySenderIsAgent ? messageText : `[${legacySenderLabel}]: ${messageText}`;
|
|
65716
|
-
Promise.resolve(this.config.onMessage?.(legacyContextualMessage, metadata)).catch((err) => {
|
|
65717
|
-
console.error("[SecureChannel] onMessage callback error:", err);
|
|
65718
|
-
});
|
|
65719
|
-
}
|
|
66404
|
+
// _sendRoomResyncIfCooled removed — rooms are MLS-only now
|
|
66405
|
+
// _handleRoomMessage removed — rooms are MLS-only now
|
|
65720
66406
|
/**
|
|
65721
66407
|
* Handle credential protocol messages (grant, revoke, request).
|
|
65722
66408
|
* These are intercepted before reaching the agent's onMessage callback.
|
|
@@ -65805,20 +66491,7 @@ ${messageText}`;
|
|
|
65805
66491
|
purgeRoomCredentials(roomId) {
|
|
65806
66492
|
this._credentialStore.purgeForRoom(roomId);
|
|
65807
66493
|
}
|
|
65808
|
-
|
|
65809
|
-
* Find the pairwise conversation ID for a given sender in a room.
|
|
65810
|
-
*/
|
|
65811
|
-
_findConversationForSender(senderDeviceId, roomId) {
|
|
65812
|
-
const room = this._persisted?.rooms?.[roomId];
|
|
65813
|
-
if (!room) return null;
|
|
65814
|
-
for (const convId of room.conversationIds) {
|
|
65815
|
-
const session = this._sessions.get(convId);
|
|
65816
|
-
if (session && session.ownerDeviceId === senderDeviceId) {
|
|
65817
|
-
return convId;
|
|
65818
|
-
}
|
|
65819
|
-
}
|
|
65820
|
-
return null;
|
|
65821
|
-
}
|
|
66494
|
+
// _findConversationForSender removed — rooms are MLS-only now
|
|
65822
66495
|
// ---------------------------------------------------------------------------
|
|
65823
66496
|
// MLS room message handlers
|
|
65824
66497
|
// ---------------------------------------------------------------------------
|
|
@@ -65842,11 +66515,33 @@ ${messageText}`;
|
|
|
65842
66515
|
return;
|
|
65843
66516
|
}
|
|
65844
66517
|
}
|
|
65845
|
-
|
|
65846
|
-
|
|
65847
|
-
|
|
66518
|
+
const resolvedRoomId = roomId;
|
|
66519
|
+
this._lastInboundRoomId = resolvedRoomId;
|
|
66520
|
+
const mlsGroup = this._mlsGroups.get(resolvedRoomId);
|
|
66521
|
+
console.log(`[SecureChannel] MLS decrypt attempt room=${resolvedRoomId.slice(0, 8)} group=${groupId?.slice(0, 8)} loaded=${!!mlsGroup} init=${mlsGroup?.isInitialized} mlsGroupsKeys=[${Array.from(this._mlsGroups.keys()).join(",")}]`);
|
|
65848
66522
|
if (!mlsGroup?.isInitialized) {
|
|
65849
|
-
console.warn(`[SecureChannel] MLS group not loaded for room ${
|
|
66523
|
+
console.warn(`[SecureChannel] MLS group not loaded for room ${resolvedRoomId.slice(0, 8)}, requesting Welcome`);
|
|
66524
|
+
try {
|
|
66525
|
+
const { MLSGroupManager: MLS } = await init_dist().then(() => dist_exports);
|
|
66526
|
+
const mgr = new MLS();
|
|
66527
|
+
const kp = await mgr.generateKeyPackage(new TextEncoder().encode(this._deviceId));
|
|
66528
|
+
const kpBytes = MLS.serializeKeyPackage(kp.publicPackage);
|
|
66529
|
+
const kpHex = Buffer.from(kpBytes).toString("hex");
|
|
66530
|
+
await fetch(`${this.config.apiUrl}/api/v1/mls/key-packages`, {
|
|
66531
|
+
method: "POST",
|
|
66532
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66533
|
+
body: JSON.stringify({ key_package: kpHex, device_id: this._deviceId })
|
|
66534
|
+
});
|
|
66535
|
+
this._pendingMlsKpBundle = kp;
|
|
66536
|
+
await fetch(`${this.config.apiUrl}/api/v1/mls/groups/${groupId}/request-welcome`, {
|
|
66537
|
+
method: "POST",
|
|
66538
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66539
|
+
body: JSON.stringify({ device_id: this._deviceId })
|
|
66540
|
+
});
|
|
66541
|
+
console.log(`[SecureChannel] Welcome requested for room ${resolvedRoomId.slice(0, 8)} group ${groupId?.slice(0, 8)}`);
|
|
66542
|
+
} catch (reqErr) {
|
|
66543
|
+
console.warn(`[SecureChannel] Welcome request failed for room ${resolvedRoomId.slice(0, 8)}:`, reqErr);
|
|
66544
|
+
}
|
|
65850
66545
|
return;
|
|
65851
66546
|
}
|
|
65852
66547
|
try {
|
|
@@ -65868,7 +66563,7 @@ ${messageText}`;
|
|
|
65868
66563
|
messageText = rawPlaintext;
|
|
65869
66564
|
}
|
|
65870
66565
|
if (CREDENTIAL_MESSAGE_TYPES.has(messageType)) {
|
|
65871
|
-
this._handleCredentialMessage(
|
|
66566
|
+
this._handleCredentialMessage(resolvedRoomId, messageType, messageText, data.message_id);
|
|
65872
66567
|
if (data.created_at && this._persisted) {
|
|
65873
66568
|
this._persisted.lastMessageTimestamp = data.created_at;
|
|
65874
66569
|
}
|
|
@@ -65883,13 +66578,13 @@ ${messageText}`;
|
|
|
65883
66578
|
}
|
|
65884
66579
|
if (data.created_at && this._persisted) {
|
|
65885
66580
|
this._persisted.lastMessageTimestamp = data.created_at;
|
|
65886
|
-
const roomState = this._persisted.rooms?.[
|
|
66581
|
+
const roomState = this._persisted.rooms?.[resolvedRoomId];
|
|
65887
66582
|
if (roomState) {
|
|
65888
66583
|
roomState.lastMlsMessageTs = data.created_at;
|
|
65889
66584
|
}
|
|
65890
66585
|
}
|
|
65891
66586
|
await this._persistState();
|
|
65892
|
-
const roomMembers = this._persisted?.rooms?.[
|
|
66587
|
+
const roomMembers = this._persisted?.rooms?.[resolvedRoomId]?.members ?? [];
|
|
65893
66588
|
const senderMember = roomMembers.find((m2) => m2.deviceId === senderDeviceId);
|
|
65894
66589
|
const senderIsAgent = senderMember?.entityType === "agent";
|
|
65895
66590
|
const metadata = {
|
|
@@ -65897,16 +66592,16 @@ ${messageText}`;
|
|
|
65897
66592
|
conversationId: "",
|
|
65898
66593
|
timestamp: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
65899
66594
|
messageType,
|
|
65900
|
-
roomId,
|
|
66595
|
+
roomId: resolvedRoomId,
|
|
65901
66596
|
senderDeviceId,
|
|
65902
66597
|
senderIsAgent,
|
|
65903
66598
|
senderName: senderMember?.displayName || "unknown",
|
|
65904
|
-
roomName: this._persisted?.rooms?.[
|
|
66599
|
+
roomName: this._persisted?.rooms?.[resolvedRoomId]?.name
|
|
65905
66600
|
};
|
|
65906
66601
|
const senderLabel = senderMember?.displayName || "someone";
|
|
65907
|
-
this._appendHistory("owner", messageText, `room:${
|
|
66602
|
+
this._appendHistory("owner", messageText, `room:${resolvedRoomId}`);
|
|
65908
66603
|
this.emit("room_message", {
|
|
65909
|
-
roomId,
|
|
66604
|
+
roomId: resolvedRoomId,
|
|
65910
66605
|
senderDeviceId,
|
|
65911
66606
|
senderName: senderLabel,
|
|
65912
66607
|
plaintext: messageText,
|
|
@@ -65918,7 +66613,7 @@ ${messageText}`;
|
|
|
65918
66613
|
console.error("[SecureChannel] onMessage callback error (MLS):", err);
|
|
65919
66614
|
});
|
|
65920
66615
|
} catch (err) {
|
|
65921
|
-
console.error(`[SecureChannel] MLS room decrypt failed for ${
|
|
66616
|
+
console.error(`[SecureChannel] MLS room decrypt failed for ${resolvedRoomId.slice(0, 8)}:`, err);
|
|
65922
66617
|
}
|
|
65923
66618
|
}
|
|
65924
66619
|
async _handleMlsCommit(data) {
|
|
@@ -65947,7 +66642,7 @@ ${messageText}`;
|
|
|
65947
66642
|
try {
|
|
65948
66643
|
const welcomeBytes = new Uint8Array(Buffer.from(data.payload, "hex"));
|
|
65949
66644
|
const mgr = new MLSGroupManager();
|
|
65950
|
-
const kp = this._mlsKeyPackage ?? await (async () => {
|
|
66645
|
+
const kp = this._pendingMlsKpBundle ?? this._mlsKeyPackage ?? await (async () => {
|
|
65951
66646
|
const identity = new TextEncoder().encode(this._deviceId);
|
|
65952
66647
|
return mgr.generateKeyPackage(identity);
|
|
65953
66648
|
})();
|
|
@@ -65964,11 +66659,15 @@ ${messageText}`;
|
|
|
65964
66659
|
console.log(`[SecureChannel] Joined 1:1 MLS group for conv ${conversationId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
|
|
65965
66660
|
return;
|
|
65966
66661
|
}
|
|
66662
|
+
const welcomeRoomId = data.room_id;
|
|
65967
66663
|
for (const [roomId, room] of Object.entries(this._persisted?.rooms ?? {})) {
|
|
65968
|
-
if (room.mlsGroupId === groupId) {
|
|
66664
|
+
if (room.mlsGroupId === groupId || roomId === welcomeRoomId) {
|
|
66665
|
+
room.mlsGroupId = groupId;
|
|
65969
66666
|
this._mlsGroups.set(roomId, mgr);
|
|
65970
66667
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
|
|
66668
|
+
await this._persistState();
|
|
65971
66669
|
console.log(`[SecureChannel] Joined MLS group for room ${roomId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
|
|
66670
|
+
this._pendingMlsKpBundle = void 0;
|
|
65972
66671
|
return;
|
|
65973
66672
|
}
|
|
65974
66673
|
}
|
|
@@ -66245,22 +66944,6 @@ ${messageText}`;
|
|
|
66245
66944
|
}
|
|
66246
66945
|
}
|
|
66247
66946
|
if (roomId) {
|
|
66248
|
-
try {
|
|
66249
|
-
await this._handleRoomMessage({
|
|
66250
|
-
room_id: roomId,
|
|
66251
|
-
sender_device_id: msg.sender_device_id,
|
|
66252
|
-
conversation_id: msg.conversation_id,
|
|
66253
|
-
header_blob: msg.header_blob,
|
|
66254
|
-
ciphertext: msg.ciphertext,
|
|
66255
|
-
message_id: msg.id,
|
|
66256
|
-
created_at: msg.created_at
|
|
66257
|
-
});
|
|
66258
|
-
} catch (roomErr) {
|
|
66259
|
-
console.warn(
|
|
66260
|
-
`[SecureChannel] Sync room message failed for ${msg.conversation_id.slice(0, 8)}...:`,
|
|
66261
|
-
roomErr
|
|
66262
|
-
);
|
|
66263
|
-
}
|
|
66264
66947
|
this._persisted.lastMessageTimestamp = msg.created_at;
|
|
66265
66948
|
since = msg.created_at;
|
|
66266
66949
|
continue;
|