@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/cli.js
CHANGED
|
@@ -44666,6 +44666,13 @@ function computeFingerprint(publicKey) {
|
|
|
44666
44666
|
function createProofOfPossession(privateKey, publicKey) {
|
|
44667
44667
|
return libsodium_wrappers_default.crypto_sign_detached(publicKey, privateKey);
|
|
44668
44668
|
}
|
|
44669
|
+
function verifyProofOfPossession(proof, publicKey) {
|
|
44670
|
+
try {
|
|
44671
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(proof, publicKey, publicKey);
|
|
44672
|
+
} catch {
|
|
44673
|
+
return false;
|
|
44674
|
+
}
|
|
44675
|
+
}
|
|
44669
44676
|
var init_keys = __esm({
|
|
44670
44677
|
async "../crypto/dist/keys.js"() {
|
|
44671
44678
|
"use strict";
|
|
@@ -45134,6 +45141,74 @@ function jsonCanonical(value) {
|
|
|
45134
45141
|
}
|
|
45135
45142
|
return JSON.stringify(value);
|
|
45136
45143
|
}
|
|
45144
|
+
function base58Encode(bytes) {
|
|
45145
|
+
let zeros = 0;
|
|
45146
|
+
for (const b2 of bytes) {
|
|
45147
|
+
if (b2 === 0)
|
|
45148
|
+
zeros++;
|
|
45149
|
+
else
|
|
45150
|
+
break;
|
|
45151
|
+
}
|
|
45152
|
+
let num = BigInt(0);
|
|
45153
|
+
for (const b2 of bytes) {
|
|
45154
|
+
num = num * 256n + BigInt(b2);
|
|
45155
|
+
}
|
|
45156
|
+
let result = "";
|
|
45157
|
+
while (num > 0n) {
|
|
45158
|
+
const remainder = Number(num % 58n);
|
|
45159
|
+
num = num / 58n;
|
|
45160
|
+
result = BASE58_ALPHABET[remainder] + result;
|
|
45161
|
+
}
|
|
45162
|
+
return "1".repeat(zeros) + result;
|
|
45163
|
+
}
|
|
45164
|
+
function base58Decode(str) {
|
|
45165
|
+
let zeros = 0;
|
|
45166
|
+
for (const c2 of str) {
|
|
45167
|
+
if (c2 === "1")
|
|
45168
|
+
zeros++;
|
|
45169
|
+
else
|
|
45170
|
+
break;
|
|
45171
|
+
}
|
|
45172
|
+
let num = BigInt(0);
|
|
45173
|
+
for (const c2 of str.slice(zeros)) {
|
|
45174
|
+
const idx = BASE58_ALPHABET.indexOf(c2);
|
|
45175
|
+
if (idx === -1)
|
|
45176
|
+
throw new Error(`Invalid base58 character: ${c2}`);
|
|
45177
|
+
num = num * 58n + BigInt(idx);
|
|
45178
|
+
}
|
|
45179
|
+
const hex3 = num === 0n ? "" : num.toString(16).padStart(2, "0");
|
|
45180
|
+
const paddedHex = hex3.length % 2 ? "0" + hex3 : hex3;
|
|
45181
|
+
const dataBytes = new Uint8Array((paddedHex.match(/.{2}/g) ?? []).map((b2) => parseInt(b2, 16)));
|
|
45182
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
45183
|
+
result.set(dataBytes, zeros);
|
|
45184
|
+
return result;
|
|
45185
|
+
}
|
|
45186
|
+
function publicKeyToMultibase(publicKey) {
|
|
45187
|
+
const prefixed = new Uint8Array(2 + publicKey.length);
|
|
45188
|
+
prefixed[0] = 237;
|
|
45189
|
+
prefixed[1] = 1;
|
|
45190
|
+
prefixed.set(publicKey, 2);
|
|
45191
|
+
return "z" + base58Encode(prefixed);
|
|
45192
|
+
}
|
|
45193
|
+
function multibaseToPublicKey(multibase) {
|
|
45194
|
+
if (!multibase.startsWith("z")) {
|
|
45195
|
+
throw new Error("Multibase string must start with 'z' (base58btc)");
|
|
45196
|
+
}
|
|
45197
|
+
const decoded = base58Decode(multibase.slice(1));
|
|
45198
|
+
if (decoded.length < 2 || decoded[0] !== 237 || decoded[1] !== 1) {
|
|
45199
|
+
throw new Error("Invalid Ed25519 multicodec prefix");
|
|
45200
|
+
}
|
|
45201
|
+
return decoded.slice(2);
|
|
45202
|
+
}
|
|
45203
|
+
async function signDocument(document, privateKey) {
|
|
45204
|
+
await libsodium_wrappers_default.ready;
|
|
45205
|
+
const canonical = canonicalize(document);
|
|
45206
|
+
const domainPrefix = libsodium_wrappers_default.from_string(DOMAIN_DID_DOCUMENT);
|
|
45207
|
+
const message = new Uint8Array(domainPrefix.length + canonical.length);
|
|
45208
|
+
message.set(domainPrefix);
|
|
45209
|
+
message.set(canonical, domainPrefix.length);
|
|
45210
|
+
return libsodium_wrappers_default.crypto_sign_detached(message, privateKey);
|
|
45211
|
+
}
|
|
45137
45212
|
async function verifyDocumentSignature(document, signature, publicKey) {
|
|
45138
45213
|
await libsodium_wrappers_default.ready;
|
|
45139
45214
|
const canonical = canonicalize(document);
|
|
@@ -45147,12 +45222,61 @@ async function verifyDocumentSignature(document, signature, publicKey) {
|
|
|
45147
45222
|
return false;
|
|
45148
45223
|
}
|
|
45149
45224
|
}
|
|
45150
|
-
|
|
45225
|
+
function buildDidDocument(params) {
|
|
45226
|
+
const { hubAddress, ownerPublicKey, agentPublicKey, serviceEndpoint, profileEndpoint } = params;
|
|
45227
|
+
const didId = `did:hub:${hubAddress}`;
|
|
45228
|
+
const ownerMultibase = publicKeyToMultibase(ownerPublicKey);
|
|
45229
|
+
const agentMultibase = publicKeyToMultibase(agentPublicKey);
|
|
45230
|
+
const controllerDid = `did:key:${ownerMultibase}`;
|
|
45231
|
+
const now = params.created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45232
|
+
return {
|
|
45233
|
+
"@context": [
|
|
45234
|
+
"https://www.w3.org/ns/did/v1",
|
|
45235
|
+
"https://w3id.org/security/suites/ed25519-2020/v1"
|
|
45236
|
+
],
|
|
45237
|
+
id: didId,
|
|
45238
|
+
controller: controllerDid,
|
|
45239
|
+
verificationMethod: [
|
|
45240
|
+
{
|
|
45241
|
+
id: `${didId}#owner-key`,
|
|
45242
|
+
type: "Ed25519VerificationKey2020",
|
|
45243
|
+
controller: didId,
|
|
45244
|
+
publicKeyMultibase: ownerMultibase
|
|
45245
|
+
},
|
|
45246
|
+
{
|
|
45247
|
+
id: `${didId}#agent-key`,
|
|
45248
|
+
type: "Ed25519VerificationKey2020",
|
|
45249
|
+
controller: didId,
|
|
45250
|
+
publicKeyMultibase: agentMultibase
|
|
45251
|
+
}
|
|
45252
|
+
],
|
|
45253
|
+
authentication: [`${didId}#owner-key`],
|
|
45254
|
+
assertionMethod: [`${didId}#owner-key`, `${didId}#agent-key`],
|
|
45255
|
+
service: [
|
|
45256
|
+
{
|
|
45257
|
+
id: `${didId}#messaging`,
|
|
45258
|
+
type: "AgentVaultSecureChannel",
|
|
45259
|
+
serviceEndpoint
|
|
45260
|
+
},
|
|
45261
|
+
{
|
|
45262
|
+
id: `${didId}#profile`,
|
|
45263
|
+
type: "AgentVaultProfile",
|
|
45264
|
+
serviceEndpoint: profileEndpoint
|
|
45265
|
+
}
|
|
45266
|
+
],
|
|
45267
|
+
created: now,
|
|
45268
|
+
updated: now
|
|
45269
|
+
};
|
|
45270
|
+
}
|
|
45271
|
+
var DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET;
|
|
45151
45272
|
var init_did = __esm({
|
|
45152
45273
|
async "../crypto/dist/did.js"() {
|
|
45153
45274
|
"use strict";
|
|
45154
45275
|
await init_libsodium_wrappers();
|
|
45155
45276
|
DOMAIN_DID_DOCUMENT = "DID-DOCUMENT:";
|
|
45277
|
+
DOMAIN_TRANSFER_INTENT = "TRANSFER-INTENT:";
|
|
45278
|
+
DOMAIN_TRANSFER_ACCEPT = "TRANSFER-ACCEPT:";
|
|
45279
|
+
BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
45156
45280
|
}
|
|
45157
45281
|
});
|
|
45158
45282
|
|
|
@@ -45435,25 +45559,373 @@ var init_scan_engine = __esm({
|
|
|
45435
45559
|
});
|
|
45436
45560
|
|
|
45437
45561
|
// ../crypto/dist/merkle.js
|
|
45562
|
+
function jcsCanonical(value) {
|
|
45563
|
+
if (value === void 0)
|
|
45564
|
+
return void 0;
|
|
45565
|
+
if (value === null)
|
|
45566
|
+
return "null";
|
|
45567
|
+
if (typeof value === "boolean" || typeof value === "number")
|
|
45568
|
+
return JSON.stringify(value);
|
|
45569
|
+
if (typeof value === "string")
|
|
45570
|
+
return JSON.stringify(value);
|
|
45571
|
+
if (Array.isArray(value)) {
|
|
45572
|
+
return "[" + value.map(jcsCanonical).join(",") + "]";
|
|
45573
|
+
}
|
|
45574
|
+
if (typeof value === "object") {
|
|
45575
|
+
const keys = Object.keys(value).sort();
|
|
45576
|
+
const entries = keys.map((k2) => {
|
|
45577
|
+
const v2 = jcsCanonical(value[k2]);
|
|
45578
|
+
if (v2 === void 0)
|
|
45579
|
+
return void 0;
|
|
45580
|
+
return JSON.stringify(k2) + ":" + v2;
|
|
45581
|
+
}).filter((entry) => entry !== void 0);
|
|
45582
|
+
return "{" + entries.join(",") + "}";
|
|
45583
|
+
}
|
|
45584
|
+
return JSON.stringify(value);
|
|
45585
|
+
}
|
|
45586
|
+
function hexToBytes(hex3) {
|
|
45587
|
+
const h2 = hex3.startsWith("0x") ? hex3.slice(2) : hex3;
|
|
45588
|
+
const bytes = new Uint8Array(h2.length / 2);
|
|
45589
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
45590
|
+
bytes[i2] = parseInt(h2.substr(i2 * 2, 2), 16);
|
|
45591
|
+
}
|
|
45592
|
+
return bytes;
|
|
45593
|
+
}
|
|
45594
|
+
function bytesToHex(bytes) {
|
|
45595
|
+
return Array.from(bytes).map((b2) => b2.toString(16).padStart(2, "0")).join("");
|
|
45596
|
+
}
|
|
45597
|
+
function computeDidHash(didDocument) {
|
|
45598
|
+
const json2 = jcsCanonical(didDocument) ?? "";
|
|
45599
|
+
const bytes = libsodium_wrappers_default.from_string(json2);
|
|
45600
|
+
const hash2 = libsodium_wrappers_default.crypto_hash_sha256(bytes);
|
|
45601
|
+
return "0x" + bytesToHex(hash2);
|
|
45602
|
+
}
|
|
45603
|
+
function verifyMerkleProof(leafHash, proof, merkleRoot) {
|
|
45604
|
+
let current = hexToBytes(leafHash);
|
|
45605
|
+
for (const step of proof) {
|
|
45606
|
+
const sibling2 = hexToBytes(step.hash);
|
|
45607
|
+
const combined = new Uint8Array(current.length + sibling2.length);
|
|
45608
|
+
if (step.position === "left") {
|
|
45609
|
+
combined.set(sibling2);
|
|
45610
|
+
combined.set(current, sibling2.length);
|
|
45611
|
+
} else {
|
|
45612
|
+
combined.set(current);
|
|
45613
|
+
combined.set(sibling2, current.length);
|
|
45614
|
+
}
|
|
45615
|
+
current = libsodium_wrappers_default.crypto_hash_sha256(combined);
|
|
45616
|
+
}
|
|
45617
|
+
const rootBytes = hexToBytes(merkleRoot);
|
|
45618
|
+
if (current.length !== rootBytes.length)
|
|
45619
|
+
return false;
|
|
45620
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
45621
|
+
if (current[i2] !== rootBytes[i2])
|
|
45622
|
+
return false;
|
|
45623
|
+
}
|
|
45624
|
+
return true;
|
|
45625
|
+
}
|
|
45438
45626
|
var init_merkle = __esm({
|
|
45439
45627
|
async "../crypto/dist/merkle.js"() {
|
|
45440
45628
|
"use strict";
|
|
45629
|
+
await init_libsodium_wrappers();
|
|
45441
45630
|
}
|
|
45442
45631
|
});
|
|
45443
45632
|
|
|
45444
45633
|
// ../crypto/dist/vc.js
|
|
45634
|
+
async function sha256(data) {
|
|
45635
|
+
await libsodium_wrappers_default.ready;
|
|
45636
|
+
return libsodium_wrappers_default.crypto_hash_sha256(data);
|
|
45637
|
+
}
|
|
45638
|
+
function base58Encode2(bytes) {
|
|
45639
|
+
let zeros = 0;
|
|
45640
|
+
for (const b2 of bytes) {
|
|
45641
|
+
if (b2 === 0)
|
|
45642
|
+
zeros++;
|
|
45643
|
+
else
|
|
45644
|
+
break;
|
|
45645
|
+
}
|
|
45646
|
+
let num = BigInt(0);
|
|
45647
|
+
for (const b2 of bytes) {
|
|
45648
|
+
num = num * 256n + BigInt(b2);
|
|
45649
|
+
}
|
|
45650
|
+
let result = "";
|
|
45651
|
+
while (num > 0n) {
|
|
45652
|
+
const remainder = Number(num % 58n);
|
|
45653
|
+
num = num / 58n;
|
|
45654
|
+
result = BASE58_ALPHABET2[remainder] + result;
|
|
45655
|
+
}
|
|
45656
|
+
return "1".repeat(zeros) + result;
|
|
45657
|
+
}
|
|
45658
|
+
function base58Decode2(str) {
|
|
45659
|
+
let zeros = 0;
|
|
45660
|
+
for (const c2 of str) {
|
|
45661
|
+
if (c2 === "1")
|
|
45662
|
+
zeros++;
|
|
45663
|
+
else
|
|
45664
|
+
break;
|
|
45665
|
+
}
|
|
45666
|
+
let num = BigInt(0);
|
|
45667
|
+
for (const c2 of str.slice(zeros)) {
|
|
45668
|
+
const idx = BASE58_ALPHABET2.indexOf(c2);
|
|
45669
|
+
if (idx === -1)
|
|
45670
|
+
throw new Error(`Invalid base58 character: ${c2}`);
|
|
45671
|
+
num = num * 58n + BigInt(idx);
|
|
45672
|
+
}
|
|
45673
|
+
const hex3 = num === 0n ? "" : num.toString(16).padStart(2, "0");
|
|
45674
|
+
const paddedHex = hex3.length % 2 ? "0" + hex3 : hex3;
|
|
45675
|
+
const dataBytes = new Uint8Array((paddedHex.match(/.{2}/g) ?? []).map((b2) => parseInt(b2, 16)));
|
|
45676
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
45677
|
+
result.set(dataBytes, zeros);
|
|
45678
|
+
return result;
|
|
45679
|
+
}
|
|
45680
|
+
async function computeHashData(document, proofConfig) {
|
|
45681
|
+
const proofConfigBytes = canonicalize(proofConfig);
|
|
45682
|
+
const proofConfigHash = await sha256(proofConfigBytes);
|
|
45683
|
+
const docWithoutProof = { ...document };
|
|
45684
|
+
delete docWithoutProof.proof;
|
|
45685
|
+
const documentBytes = canonicalize(docWithoutProof);
|
|
45686
|
+
const documentHash = await sha256(documentBytes);
|
|
45687
|
+
const hashData = new Uint8Array(64);
|
|
45688
|
+
hashData.set(proofConfigHash, 0);
|
|
45689
|
+
hashData.set(documentHash, 32);
|
|
45690
|
+
return hashData;
|
|
45691
|
+
}
|
|
45692
|
+
async function signWithDataIntegrity(document, privateKey, verificationMethod, proofPurpose = "assertionMethod", created) {
|
|
45693
|
+
await libsodium_wrappers_default.ready;
|
|
45694
|
+
const timestamp = created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45695
|
+
const proofConfig = {
|
|
45696
|
+
type: "DataIntegrityProof",
|
|
45697
|
+
cryptosuite: CRYPTOSUITE,
|
|
45698
|
+
created: timestamp,
|
|
45699
|
+
verificationMethod,
|
|
45700
|
+
proofPurpose
|
|
45701
|
+
};
|
|
45702
|
+
const hashData = await computeHashData(document, proofConfig);
|
|
45703
|
+
const signature = libsodium_wrappers_default.crypto_sign_detached(hashData, privateKey);
|
|
45704
|
+
const proofValue = "z" + base58Encode2(signature);
|
|
45705
|
+
const proof = {
|
|
45706
|
+
type: "DataIntegrityProof",
|
|
45707
|
+
cryptosuite: CRYPTOSUITE,
|
|
45708
|
+
created: timestamp,
|
|
45709
|
+
verificationMethod,
|
|
45710
|
+
proofPurpose,
|
|
45711
|
+
proofValue
|
|
45712
|
+
};
|
|
45713
|
+
return { ...document, proof };
|
|
45714
|
+
}
|
|
45715
|
+
async function verifyDataIntegrity(document, publicKey) {
|
|
45716
|
+
await libsodium_wrappers_default.ready;
|
|
45717
|
+
const proof = document.proof;
|
|
45718
|
+
if (!proof || proof.type !== "DataIntegrityProof" || proof.cryptosuite !== CRYPTOSUITE) {
|
|
45719
|
+
return false;
|
|
45720
|
+
}
|
|
45721
|
+
if (!proof.proofValue.startsWith("z")) {
|
|
45722
|
+
return false;
|
|
45723
|
+
}
|
|
45724
|
+
const signature = base58Decode2(proof.proofValue.slice(1));
|
|
45725
|
+
if (signature.length !== 64) {
|
|
45726
|
+
return false;
|
|
45727
|
+
}
|
|
45728
|
+
const proofConfig = {
|
|
45729
|
+
type: proof.type,
|
|
45730
|
+
cryptosuite: proof.cryptosuite,
|
|
45731
|
+
created: proof.created,
|
|
45732
|
+
verificationMethod: proof.verificationMethod,
|
|
45733
|
+
proofPurpose: proof.proofPurpose
|
|
45734
|
+
};
|
|
45735
|
+
const hashData = await computeHashData(document, proofConfig);
|
|
45736
|
+
try {
|
|
45737
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(signature, hashData, publicKey);
|
|
45738
|
+
} catch {
|
|
45739
|
+
return false;
|
|
45740
|
+
}
|
|
45741
|
+
}
|
|
45742
|
+
function buildAgentTrustCredential(params) {
|
|
45743
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45744
|
+
return {
|
|
45745
|
+
"@context": [
|
|
45746
|
+
VC_CONTEXT_V2,
|
|
45747
|
+
{
|
|
45748
|
+
AgentTrustCredential: "https://agentvault.chat/vocab#AgentTrustCredential",
|
|
45749
|
+
trustTier: "https://agentvault.chat/vocab#trustTier",
|
|
45750
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore",
|
|
45751
|
+
scoreWindow: "https://agentvault.chat/vocab#scoreWindow",
|
|
45752
|
+
scoreDimensions: "https://agentvault.chat/vocab#scoreDimensions",
|
|
45753
|
+
volume: "https://agentvault.chat/vocab#volume",
|
|
45754
|
+
responsiveness: "https://agentvault.chat/vocab#responsiveness",
|
|
45755
|
+
uptime: "https://agentvault.chat/vocab#uptime",
|
|
45756
|
+
compliance: "https://agentvault.chat/vocab#compliance",
|
|
45757
|
+
verificationEndpoint: "https://agentvault.chat/vocab#verificationEndpoint"
|
|
45758
|
+
}
|
|
45759
|
+
],
|
|
45760
|
+
id: params.credentialId,
|
|
45761
|
+
type: ["VerifiableCredential", "AgentTrustCredential"],
|
|
45762
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45763
|
+
validFrom: params.validFrom ?? now,
|
|
45764
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45765
|
+
credentialSubject: {
|
|
45766
|
+
id: params.subjectDid,
|
|
45767
|
+
trustTier: params.trustTier,
|
|
45768
|
+
compositeScore: params.compositeScore,
|
|
45769
|
+
scoreWindow: params.scoreWindow,
|
|
45770
|
+
...params.dimensions ? {
|
|
45771
|
+
scoreDimensions: {
|
|
45772
|
+
volume: params.dimensions.volume,
|
|
45773
|
+
responsiveness: params.dimensions.responsiveness,
|
|
45774
|
+
uptime: params.dimensions.uptime,
|
|
45775
|
+
compliance: params.dimensions.compliance
|
|
45776
|
+
}
|
|
45777
|
+
} : {},
|
|
45778
|
+
...params.verificationEndpoint ? { verificationEndpoint: params.verificationEndpoint } : {}
|
|
45779
|
+
}
|
|
45780
|
+
};
|
|
45781
|
+
}
|
|
45782
|
+
function buildSkillAttestation(params) {
|
|
45783
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45784
|
+
return {
|
|
45785
|
+
"@context": [
|
|
45786
|
+
VC_CONTEXT_V2,
|
|
45787
|
+
{
|
|
45788
|
+
SkillAttestation: "https://agentvault.chat/vocab#SkillAttestation",
|
|
45789
|
+
skillName: "https://agentvault.chat/vocab#skillName",
|
|
45790
|
+
skillNamespace: "https://agentvault.chat/vocab#skillNamespace",
|
|
45791
|
+
proficiencyLevel: "https://agentvault.chat/vocab#proficiencyLevel",
|
|
45792
|
+
totalInvocations: "https://agentvault.chat/vocab#totalInvocations",
|
|
45793
|
+
successRate: "https://agentvault.chat/vocab#successRate",
|
|
45794
|
+
assessedAt: "https://agentvault.chat/vocab#assessedAt"
|
|
45795
|
+
}
|
|
45796
|
+
],
|
|
45797
|
+
id: params.credentialId,
|
|
45798
|
+
type: ["VerifiableCredential", "SkillAttestation"],
|
|
45799
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45800
|
+
validFrom: params.validFrom ?? now,
|
|
45801
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45802
|
+
credentialSubject: {
|
|
45803
|
+
id: params.subjectDid,
|
|
45804
|
+
skillName: params.skillName,
|
|
45805
|
+
skillNamespace: params.skillNamespace,
|
|
45806
|
+
...params.proficiencyLevel ? { proficiencyLevel: params.proficiencyLevel } : {},
|
|
45807
|
+
...params.totalInvocations !== void 0 ? { totalInvocations: params.totalInvocations } : {},
|
|
45808
|
+
...params.successRate !== void 0 ? { successRate: params.successRate } : {},
|
|
45809
|
+
...params.assessedAt ? { assessedAt: params.assessedAt } : {}
|
|
45810
|
+
}
|
|
45811
|
+
};
|
|
45812
|
+
}
|
|
45813
|
+
function buildPerformanceRecord(params) {
|
|
45814
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45815
|
+
return {
|
|
45816
|
+
"@context": [
|
|
45817
|
+
VC_CONTEXT_V2,
|
|
45818
|
+
{
|
|
45819
|
+
PerformanceRecord: "https://agentvault.chat/vocab#PerformanceRecord",
|
|
45820
|
+
periodStart: "https://agentvault.chat/vocab#periodStart",
|
|
45821
|
+
periodEnd: "https://agentvault.chat/vocab#periodEnd",
|
|
45822
|
+
messagesHandled: "https://agentvault.chat/vocab#messagesHandled",
|
|
45823
|
+
avgResponseTimeMs: "https://agentvault.chat/vocab#avgResponseTimeMs",
|
|
45824
|
+
uptimePercentage: "https://agentvault.chat/vocab#uptimePercentage",
|
|
45825
|
+
policyViolations: "https://agentvault.chat/vocab#policyViolations",
|
|
45826
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore"
|
|
45827
|
+
}
|
|
45828
|
+
],
|
|
45829
|
+
id: params.credentialId,
|
|
45830
|
+
type: ["VerifiableCredential", "PerformanceRecord"],
|
|
45831
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45832
|
+
validFrom: params.validFrom ?? now,
|
|
45833
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45834
|
+
credentialSubject: {
|
|
45835
|
+
id: params.subjectDid,
|
|
45836
|
+
periodStart: params.periodStart,
|
|
45837
|
+
periodEnd: params.periodEnd,
|
|
45838
|
+
messagesHandled: params.messagesHandled,
|
|
45839
|
+
avgResponseTimeMs: params.avgResponseTimeMs,
|
|
45840
|
+
uptimePercentage: params.uptimePercentage,
|
|
45841
|
+
policyViolations: params.policyViolations,
|
|
45842
|
+
compositeScore: params.compositeScore
|
|
45843
|
+
}
|
|
45844
|
+
};
|
|
45845
|
+
}
|
|
45846
|
+
function buildAgentTrustReportCredential(params) {
|
|
45847
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45848
|
+
const subject = {
|
|
45849
|
+
id: params.subjectDid,
|
|
45850
|
+
reportPeriod: {
|
|
45851
|
+
start: params.reportPeriodStart,
|
|
45852
|
+
end: params.reportPeriodEnd
|
|
45853
|
+
},
|
|
45854
|
+
trustTier: params.trustTier,
|
|
45855
|
+
compositeScore: params.compositeScore
|
|
45856
|
+
};
|
|
45857
|
+
if (params.dimensions)
|
|
45858
|
+
subject.dimensions = params.dimensions;
|
|
45859
|
+
if (params.trending)
|
|
45860
|
+
subject.trending = params.trending;
|
|
45861
|
+
if (params.fleetComparison)
|
|
45862
|
+
subject.fleetComparison = params.fleetComparison;
|
|
45863
|
+
if (params.driftStatus)
|
|
45864
|
+
subject.driftStatus = params.driftStatus;
|
|
45865
|
+
if (params.auditIntegrity)
|
|
45866
|
+
subject.auditIntegrity = params.auditIntegrity;
|
|
45867
|
+
if (params.telemetrySummary)
|
|
45868
|
+
subject.telemetrySummary = params.telemetrySummary;
|
|
45869
|
+
if (params.verificationEndpoint)
|
|
45870
|
+
subject.verificationEndpoint = params.verificationEndpoint;
|
|
45871
|
+
return {
|
|
45872
|
+
"@context": [
|
|
45873
|
+
VC_CONTEXT_V2,
|
|
45874
|
+
{
|
|
45875
|
+
AgentTrustReport: "https://agentvault.chat/vocab#AgentTrustReport",
|
|
45876
|
+
reportPeriod: "https://agentvault.chat/vocab#reportPeriod",
|
|
45877
|
+
trustTier: "https://agentvault.chat/vocab#trustTier",
|
|
45878
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore",
|
|
45879
|
+
dimensions: "https://agentvault.chat/vocab#dimensions",
|
|
45880
|
+
trending: "https://agentvault.chat/vocab#trending",
|
|
45881
|
+
fleetComparison: "https://agentvault.chat/vocab#fleetComparison",
|
|
45882
|
+
driftStatus: "https://agentvault.chat/vocab#driftStatus",
|
|
45883
|
+
auditIntegrity: "https://agentvault.chat/vocab#auditIntegrity",
|
|
45884
|
+
telemetrySummary: "https://agentvault.chat/vocab#telemetrySummary",
|
|
45885
|
+
verificationEndpoint: "https://agentvault.chat/vocab#verificationEndpoint"
|
|
45886
|
+
}
|
|
45887
|
+
],
|
|
45888
|
+
id: params.credentialId,
|
|
45889
|
+
type: ["VerifiableCredential", "AgentTrustReport"],
|
|
45890
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45891
|
+
validFrom: params.validFrom ?? now,
|
|
45892
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45893
|
+
credentialSubject: subject
|
|
45894
|
+
};
|
|
45895
|
+
}
|
|
45896
|
+
function buildVerifiablePresentation(holderDid, credentials, presentationId) {
|
|
45897
|
+
return {
|
|
45898
|
+
"@context": [VC_CONTEXT_V2],
|
|
45899
|
+
type: "VerifiablePresentation",
|
|
45900
|
+
...presentationId ? { id: presentationId } : {},
|
|
45901
|
+
holder: holderDid,
|
|
45902
|
+
verifiableCredential: credentials
|
|
45903
|
+
};
|
|
45904
|
+
}
|
|
45905
|
+
async function issueCredential(credential, privateKey, verificationMethod) {
|
|
45906
|
+
return signWithDataIntegrity(credential, privateKey, verificationMethod, "assertionMethod");
|
|
45907
|
+
}
|
|
45908
|
+
async function presentCredentials(presentation, privateKey, verificationMethod) {
|
|
45909
|
+
return signWithDataIntegrity(presentation, privateKey, verificationMethod, "authentication");
|
|
45910
|
+
}
|
|
45911
|
+
var VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2;
|
|
45445
45912
|
var init_vc = __esm({
|
|
45446
45913
|
async "../crypto/dist/vc.js"() {
|
|
45447
45914
|
"use strict";
|
|
45915
|
+
await init_libsodium_wrappers();
|
|
45448
45916
|
await init_did();
|
|
45917
|
+
VC_CONTEXT_V2 = "https://www.w3.org/ns/credentials/v2";
|
|
45918
|
+
AV_CREDENTIAL_CONTEXT = "https://agentvault.chat/ns/credentials/v1";
|
|
45919
|
+
CRYPTOSUITE = "eddsa-jcs-2022";
|
|
45920
|
+
BASE58_ALPHABET2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
45449
45921
|
}
|
|
45450
45922
|
});
|
|
45451
45923
|
|
|
45452
45924
|
// ../crypto/dist/transport.js
|
|
45453
|
-
function
|
|
45925
|
+
function hexToBytes2(hex3) {
|
|
45454
45926
|
return libsodium_wrappers_default.from_hex(hex3);
|
|
45455
45927
|
}
|
|
45456
|
-
function
|
|
45928
|
+
function bytesToHex2(bytes) {
|
|
45457
45929
|
return libsodium_wrappers_default.to_hex(bytes);
|
|
45458
45930
|
}
|
|
45459
45931
|
function base64ToBytes(b64) {
|
|
@@ -45491,6 +45963,70 @@ function transportToEncryptedMessage(transport) {
|
|
|
45491
45963
|
ciphertext: base64ToBytes(transport.ciphertext)
|
|
45492
45964
|
};
|
|
45493
45965
|
}
|
|
45966
|
+
function encryptedMessageToTransportV2(msg) {
|
|
45967
|
+
if (!msg.encryptedHeader || !msg.headerNonce) {
|
|
45968
|
+
throw new Error("encryptedMessageToTransportV2 requires v2 encrypted message");
|
|
45969
|
+
}
|
|
45970
|
+
return {
|
|
45971
|
+
envelope_version: "2.0.0",
|
|
45972
|
+
encrypted_header: bytesToBase64(msg.encryptedHeader),
|
|
45973
|
+
header_nonce: bytesToBase64(msg.headerNonce),
|
|
45974
|
+
header_signature: bytesToBase64(msg.headerSignature),
|
|
45975
|
+
nonce: bytesToBase64(msg.nonce),
|
|
45976
|
+
ciphertext: bytesToBase64(msg.ciphertext)
|
|
45977
|
+
};
|
|
45978
|
+
}
|
|
45979
|
+
function transportV2ToEncryptedMessage(transport, plaintextHeader) {
|
|
45980
|
+
return {
|
|
45981
|
+
header: plaintextHeader,
|
|
45982
|
+
headerSignature: base64ToBytes(transport.header_signature),
|
|
45983
|
+
ciphertext: base64ToBytes(transport.ciphertext),
|
|
45984
|
+
nonce: base64ToBytes(transport.nonce),
|
|
45985
|
+
envelopeVersion: "2.0.0",
|
|
45986
|
+
encryptedHeader: base64ToBytes(transport.encrypted_header),
|
|
45987
|
+
headerNonce: base64ToBytes(transport.header_nonce)
|
|
45988
|
+
};
|
|
45989
|
+
}
|
|
45990
|
+
function encryptedMessageToTransportV2Full(msg) {
|
|
45991
|
+
if (!msg.encryptedHeader || !msg.headerNonce) {
|
|
45992
|
+
throw new Error("encryptedMessageToTransportV2Full requires v2 encrypted message");
|
|
45993
|
+
}
|
|
45994
|
+
const v1 = encryptedMessageToTransport(msg);
|
|
45995
|
+
return {
|
|
45996
|
+
...v1,
|
|
45997
|
+
envelope_version: "2.0.0",
|
|
45998
|
+
encrypted_header: bytesToBase64(msg.encryptedHeader),
|
|
45999
|
+
header_nonce: bytesToBase64(msg.headerNonce)
|
|
46000
|
+
};
|
|
46001
|
+
}
|
|
46002
|
+
function encryptedMessageToHexTransport(msg) {
|
|
46003
|
+
const headerObj = {
|
|
46004
|
+
dhPublicKey: bytesToHex2(msg.header.dhPublicKey),
|
|
46005
|
+
previousChainLength: msg.header.previousChainLength,
|
|
46006
|
+
messageNumber: msg.header.messageNumber
|
|
46007
|
+
};
|
|
46008
|
+
const headerBlobHex = Buffer.from(JSON.stringify(headerObj)).toString("hex");
|
|
46009
|
+
return {
|
|
46010
|
+
header_blob: headerBlobHex,
|
|
46011
|
+
header_signature: bytesToHex2(msg.headerSignature),
|
|
46012
|
+
ciphertext: bytesToHex2(msg.ciphertext),
|
|
46013
|
+
nonce: bytesToHex2(msg.nonce)
|
|
46014
|
+
};
|
|
46015
|
+
}
|
|
46016
|
+
function hexTransportToEncryptedMessage(transport) {
|
|
46017
|
+
const headerJson = Buffer.from(transport.header_blob, "hex").toString("utf-8");
|
|
46018
|
+
const headerObj = JSON.parse(headerJson);
|
|
46019
|
+
return {
|
|
46020
|
+
header: {
|
|
46021
|
+
dhPublicKey: hexToBytes2(headerObj.dhPublicKey),
|
|
46022
|
+
previousChainLength: headerObj.previousChainLength,
|
|
46023
|
+
messageNumber: headerObj.messageNumber
|
|
46024
|
+
},
|
|
46025
|
+
headerSignature: hexToBytes2(transport.header_signature),
|
|
46026
|
+
ciphertext: hexToBytes2(transport.ciphertext),
|
|
46027
|
+
nonce: hexToBytes2(transport.nonce)
|
|
46028
|
+
};
|
|
46029
|
+
}
|
|
45494
46030
|
var init_transport = __esm({
|
|
45495
46031
|
async "../crypto/dist/transport.js"() {
|
|
45496
46032
|
"use strict";
|
|
@@ -45695,6 +46231,40 @@ function buildTaskSpan(opts) {
|
|
|
45695
46231
|
status
|
|
45696
46232
|
};
|
|
45697
46233
|
}
|
|
46234
|
+
function buildSkillInvocationSpan(opts) {
|
|
46235
|
+
const now = Date.now();
|
|
46236
|
+
const attributes = {
|
|
46237
|
+
"ai.agent.skill.invocation.id": opts.invocationId,
|
|
46238
|
+
"ai.agent.skill.phase": opts.phase
|
|
46239
|
+
};
|
|
46240
|
+
if (opts.skillName)
|
|
46241
|
+
attributes["ai.agent.skill.name"] = opts.skillName;
|
|
46242
|
+
if (opts.version !== void 0)
|
|
46243
|
+
attributes["ai.agent.skill.version"] = opts.version;
|
|
46244
|
+
if (opts.inputTokens !== void 0)
|
|
46245
|
+
attributes["ai.agent.skill.input_tokens"] = opts.inputTokens;
|
|
46246
|
+
if (opts.outputTokens !== void 0)
|
|
46247
|
+
attributes["ai.agent.skill.output_tokens"] = opts.outputTokens;
|
|
46248
|
+
if (opts.costCents !== void 0)
|
|
46249
|
+
attributes["ai.agent.skill.cost_cents"] = opts.costCents;
|
|
46250
|
+
if (opts.toolsUsed !== void 0)
|
|
46251
|
+
attributes["ai.agent.skill.tools_used"] = opts.toolsUsed.join(",");
|
|
46252
|
+
if (opts.schemaMatch !== void 0)
|
|
46253
|
+
attributes["ai.agent.skill.schema_match"] = opts.schemaMatch;
|
|
46254
|
+
const isError = opts.status === "error";
|
|
46255
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46256
|
+
return {
|
|
46257
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46258
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46259
|
+
parentSpanId: opts.parentSpanId,
|
|
46260
|
+
name: "skill.invoke",
|
|
46261
|
+
kind: "internal",
|
|
46262
|
+
startTime: now - opts.latencyMs,
|
|
46263
|
+
endTime: now,
|
|
46264
|
+
attributes,
|
|
46265
|
+
status
|
|
46266
|
+
};
|
|
46267
|
+
}
|
|
45698
46268
|
function buildEvalSpan(opts) {
|
|
45699
46269
|
const now = Date.now();
|
|
45700
46270
|
const attributes = {
|
|
@@ -45717,12 +46287,364 @@ function buildEvalSpan(opts) {
|
|
|
45717
46287
|
startTime: now,
|
|
45718
46288
|
endTime: now,
|
|
45719
46289
|
attributes,
|
|
45720
|
-
status: { code: 0 }
|
|
46290
|
+
status: { code: 0 }
|
|
46291
|
+
};
|
|
46292
|
+
}
|
|
46293
|
+
function buildForgeSpan(opts) {
|
|
46294
|
+
const now = Date.now();
|
|
46295
|
+
const attributes = {
|
|
46296
|
+
"ai.agent.forge.session_id": opts.forgeSessionId,
|
|
46297
|
+
"ai.agent.forge.phase": opts.phase
|
|
46298
|
+
};
|
|
46299
|
+
if (opts.stageNumber !== void 0)
|
|
46300
|
+
attributes["ai.agent.forge.stage_number"] = opts.stageNumber;
|
|
46301
|
+
if (opts.artifactCount !== void 0)
|
|
46302
|
+
attributes["ai.agent.forge.artifact_count"] = opts.artifactCount;
|
|
46303
|
+
if (opts.scanStatus !== void 0)
|
|
46304
|
+
attributes["ai.agent.forge.scan_status"] = opts.scanStatus;
|
|
46305
|
+
applySkillName(attributes, opts.skillName);
|
|
46306
|
+
const isError = opts.status === "error";
|
|
46307
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46308
|
+
return {
|
|
46309
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46310
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46311
|
+
parentSpanId: opts.parentSpanId,
|
|
46312
|
+
name: `forge.${opts.phase}`,
|
|
46313
|
+
kind: "internal",
|
|
46314
|
+
startTime: now - opts.latencyMs,
|
|
46315
|
+
endTime: now,
|
|
46316
|
+
attributes,
|
|
46317
|
+
status
|
|
46318
|
+
};
|
|
46319
|
+
}
|
|
46320
|
+
function buildPolicyViolationSpan(opts) {
|
|
46321
|
+
const now = Date.now();
|
|
46322
|
+
const attributes = {
|
|
46323
|
+
"av.policy.rule_id": opts.ruleId,
|
|
46324
|
+
"av.policy.scope": opts.policyScope,
|
|
46325
|
+
"av.policy.action_taken": opts.actionTaken,
|
|
46326
|
+
"av.policy.violation_type": opts.violationType
|
|
46327
|
+
};
|
|
46328
|
+
if (opts.targetTool)
|
|
46329
|
+
attributes["av.policy.target_tool"] = opts.targetTool;
|
|
46330
|
+
if (opts.targetModel)
|
|
46331
|
+
attributes["av.policy.target_model"] = opts.targetModel;
|
|
46332
|
+
if (opts.messageType)
|
|
46333
|
+
attributes["av.policy.message_type"] = opts.messageType;
|
|
46334
|
+
applySkillName(attributes, opts.skillName);
|
|
46335
|
+
const isBlock = opts.actionTaken === "block";
|
|
46336
|
+
return {
|
|
46337
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46338
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46339
|
+
parentSpanId: opts.parentSpanId,
|
|
46340
|
+
name: "av.policy.evaluate",
|
|
46341
|
+
kind: "internal",
|
|
46342
|
+
startTime: now,
|
|
46343
|
+
endTime: now,
|
|
46344
|
+
attributes,
|
|
46345
|
+
status: isBlock ? { code: 2, message: `Policy violation: ${opts.violationType}` } : { code: 0 }
|
|
46346
|
+
};
|
|
46347
|
+
}
|
|
46348
|
+
function buildDecisionSpan(opts) {
|
|
46349
|
+
const now = Date.now();
|
|
46350
|
+
const attributes = {
|
|
46351
|
+
"av.decision.id": opts.decisionId,
|
|
46352
|
+
"av.decision.phase": opts.phase
|
|
46353
|
+
};
|
|
46354
|
+
if (opts.priority)
|
|
46355
|
+
attributes["av.decision.priority"] = opts.priority;
|
|
46356
|
+
if (opts.category)
|
|
46357
|
+
attributes["av.decision.category"] = opts.category;
|
|
46358
|
+
applySkillName(attributes, opts.skillName);
|
|
46359
|
+
const isError = opts.status === "error";
|
|
46360
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46361
|
+
return {
|
|
46362
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46363
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46364
|
+
parentSpanId: opts.parentSpanId,
|
|
46365
|
+
name: "av.decision",
|
|
46366
|
+
kind: "internal",
|
|
46367
|
+
startTime: now - opts.latencyMs,
|
|
46368
|
+
endTime: now,
|
|
46369
|
+
attributes,
|
|
46370
|
+
status
|
|
46371
|
+
};
|
|
46372
|
+
}
|
|
46373
|
+
function buildResyncSpan(opts) {
|
|
46374
|
+
const now = Date.now();
|
|
46375
|
+
const attributes = {
|
|
46376
|
+
"av.resync.conversation_id": opts.conversationId,
|
|
46377
|
+
"av.resync.phase": opts.phase
|
|
46378
|
+
};
|
|
46379
|
+
if (opts.reason)
|
|
46380
|
+
attributes["av.resync.reason"] = opts.reason;
|
|
46381
|
+
applySkillName(attributes, opts.skillName);
|
|
46382
|
+
const isError = opts.status === "error";
|
|
46383
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46384
|
+
return {
|
|
46385
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46386
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46387
|
+
parentSpanId: opts.parentSpanId,
|
|
46388
|
+
name: "av.resync",
|
|
46389
|
+
kind: "internal",
|
|
46390
|
+
startTime: now - opts.latencyMs,
|
|
46391
|
+
endTime: now,
|
|
46392
|
+
attributes,
|
|
46393
|
+
status
|
|
46394
|
+
};
|
|
46395
|
+
}
|
|
46396
|
+
function buildA2aSpan(opts) {
|
|
46397
|
+
const now = Date.now();
|
|
46398
|
+
const attributes = {
|
|
46399
|
+
"av.a2a.channel_id": opts.channelId,
|
|
46400
|
+
"av.a2a.operation": opts.operation
|
|
46401
|
+
};
|
|
46402
|
+
if (opts.peerHubAddress)
|
|
46403
|
+
attributes["av.a2a.peer_hub_address"] = opts.peerHubAddress;
|
|
46404
|
+
if (opts.role)
|
|
46405
|
+
attributes["av.a2a.role"] = opts.role;
|
|
46406
|
+
applySkillName(attributes, opts.skillName);
|
|
46407
|
+
const isError = opts.status === "error";
|
|
46408
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46409
|
+
return {
|
|
46410
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46411
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46412
|
+
parentSpanId: opts.parentSpanId,
|
|
46413
|
+
name: "av.a2a",
|
|
46414
|
+
kind: "internal",
|
|
46415
|
+
startTime: now - opts.latencyMs,
|
|
46416
|
+
endTime: now,
|
|
46417
|
+
attributes,
|
|
46418
|
+
status
|
|
46419
|
+
};
|
|
46420
|
+
}
|
|
46421
|
+
function buildScanSpan(opts) {
|
|
46422
|
+
const now = Date.now();
|
|
46423
|
+
const attributes = {
|
|
46424
|
+
"av.scan.target": opts.scanTarget,
|
|
46425
|
+
"av.scan.type": opts.scanType,
|
|
46426
|
+
"av.scan.violation_count": opts.violationCount,
|
|
46427
|
+
"av.scan.rule_count": opts.ruleCount
|
|
46428
|
+
};
|
|
46429
|
+
applySkillName(attributes, opts.skillName);
|
|
46430
|
+
const isError = opts.status === "error" || opts.violationCount > 0;
|
|
46431
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46432
|
+
return {
|
|
46433
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46434
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46435
|
+
parentSpanId: opts.parentSpanId,
|
|
46436
|
+
name: "av.scan",
|
|
46437
|
+
kind: "internal",
|
|
46438
|
+
startTime: now - opts.latencyMs,
|
|
46439
|
+
endTime: now,
|
|
46440
|
+
attributes,
|
|
46441
|
+
status
|
|
46442
|
+
};
|
|
46443
|
+
}
|
|
46444
|
+
function buildWorkspaceSpan(opts) {
|
|
46445
|
+
const now = Date.now();
|
|
46446
|
+
const attributes = {
|
|
46447
|
+
"av.workspace.id": opts.workspaceId,
|
|
46448
|
+
"av.workspace.operation": opts.operation
|
|
46449
|
+
};
|
|
46450
|
+
if (opts.fileName)
|
|
46451
|
+
attributes["av.workspace.file_name"] = opts.fileName;
|
|
46452
|
+
if (opts.fileSizeBytes !== void 0)
|
|
46453
|
+
attributes["av.workspace.file_size_bytes"] = opts.fileSizeBytes;
|
|
46454
|
+
if (opts.encrypted !== void 0)
|
|
46455
|
+
attributes["av.workspace.encrypted"] = opts.encrypted;
|
|
46456
|
+
applySkillName(attributes, opts.skillName);
|
|
46457
|
+
const isError = opts.status === "error";
|
|
46458
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46459
|
+
return {
|
|
46460
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46461
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46462
|
+
parentSpanId: opts.parentSpanId,
|
|
46463
|
+
name: "av.workspace",
|
|
46464
|
+
kind: "internal",
|
|
46465
|
+
startTime: now - opts.latencyMs,
|
|
46466
|
+
endTime: now,
|
|
46467
|
+
attributes,
|
|
46468
|
+
status
|
|
46469
|
+
};
|
|
46470
|
+
}
|
|
46471
|
+
function buildCapabilitySpan(opts) {
|
|
46472
|
+
const now = Date.now();
|
|
46473
|
+
const attributes = {
|
|
46474
|
+
"av.skill.operation": opts.operation,
|
|
46475
|
+
"av.skill.success": opts.success
|
|
46476
|
+
};
|
|
46477
|
+
if (opts.skillName)
|
|
46478
|
+
attributes["av.skill.name"] = opts.skillName;
|
|
46479
|
+
if (opts.version)
|
|
46480
|
+
attributes["av.skill.version"] = opts.version;
|
|
46481
|
+
if (opts.certificationTier)
|
|
46482
|
+
attributes["av.skill.certification_tier"] = opts.certificationTier;
|
|
46483
|
+
if (opts.toolsUsed?.length)
|
|
46484
|
+
attributes["av.skill.tools_used"] = opts.toolsUsed.join(",");
|
|
46485
|
+
const status = opts.success ? { code: 0 } : { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} };
|
|
46486
|
+
return {
|
|
46487
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46488
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46489
|
+
parentSpanId: opts.parentSpanId,
|
|
46490
|
+
name: "av.skill.invoke",
|
|
46491
|
+
kind: "internal",
|
|
46492
|
+
startTime: now - opts.latencyMs,
|
|
46493
|
+
endTime: now,
|
|
46494
|
+
attributes,
|
|
46495
|
+
status
|
|
46496
|
+
};
|
|
46497
|
+
}
|
|
46498
|
+
function buildEnrollmentSpan(opts) {
|
|
46499
|
+
const now = Date.now();
|
|
46500
|
+
const attributes = {
|
|
46501
|
+
"av.enrollment.phase": opts.phase
|
|
46502
|
+
};
|
|
46503
|
+
if (opts.deviceId)
|
|
46504
|
+
attributes["av.enrollment.device_id"] = opts.deviceId;
|
|
46505
|
+
if (opts.enrollmentType)
|
|
46506
|
+
attributes["av.enrollment.type"] = opts.enrollmentType;
|
|
46507
|
+
applySkillName(attributes, opts.skillName);
|
|
46508
|
+
const isError = opts.status === "error" || opts.phase === "fail";
|
|
46509
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46510
|
+
return {
|
|
46511
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46512
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46513
|
+
parentSpanId: opts.parentSpanId,
|
|
46514
|
+
name: "av.enrollment",
|
|
46515
|
+
kind: "internal",
|
|
46516
|
+
startTime: now - opts.latencyMs,
|
|
46517
|
+
endTime: now,
|
|
46518
|
+
attributes,
|
|
46519
|
+
status
|
|
46520
|
+
};
|
|
46521
|
+
}
|
|
46522
|
+
function buildRoomSpan(opts) {
|
|
46523
|
+
const now = Date.now();
|
|
46524
|
+
const attributes = {
|
|
46525
|
+
"av.room.id": opts.roomId,
|
|
46526
|
+
"av.room.operation": opts.operation
|
|
46527
|
+
};
|
|
46528
|
+
if (opts.roomName)
|
|
46529
|
+
attributes["av.room.name"] = opts.roomName;
|
|
46530
|
+
if (opts.memberCount !== void 0)
|
|
46531
|
+
attributes["av.room.member_count"] = opts.memberCount;
|
|
46532
|
+
applySkillName(attributes, opts.skillName);
|
|
46533
|
+
const isError = opts.status === "error";
|
|
46534
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46535
|
+
return {
|
|
46536
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46537
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46538
|
+
parentSpanId: opts.parentSpanId,
|
|
46539
|
+
name: "av.room",
|
|
46540
|
+
kind: "internal",
|
|
46541
|
+
startTime: now - opts.latencyMs,
|
|
46542
|
+
endTime: now,
|
|
46543
|
+
attributes,
|
|
46544
|
+
status
|
|
46545
|
+
};
|
|
46546
|
+
}
|
|
46547
|
+
function buildTrustSpan(opts) {
|
|
46548
|
+
const now = Date.now();
|
|
46549
|
+
const attributes = {
|
|
46550
|
+
"av.trust.agent_hub_address": opts.agentHubAddress,
|
|
46551
|
+
"av.trust.operation": opts.operation
|
|
46552
|
+
};
|
|
46553
|
+
if (opts.previousTier)
|
|
46554
|
+
attributes["av.trust.previous_tier"] = opts.previousTier;
|
|
46555
|
+
if (opts.newTier)
|
|
46556
|
+
attributes["av.trust.new_tier"] = opts.newTier;
|
|
46557
|
+
if (opts.overallScore !== void 0)
|
|
46558
|
+
attributes["av.trust.overall_score"] = opts.overallScore;
|
|
46559
|
+
if (opts.dimension)
|
|
46560
|
+
attributes["av.trust.dimension"] = opts.dimension;
|
|
46561
|
+
if (opts.dimensionScore !== void 0)
|
|
46562
|
+
attributes["av.trust.dimension_score"] = opts.dimensionScore;
|
|
46563
|
+
applySkillName(attributes, opts.skillName);
|
|
46564
|
+
const isError = opts.status === "error";
|
|
46565
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46566
|
+
return {
|
|
46567
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46568
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46569
|
+
parentSpanId: opts.parentSpanId,
|
|
46570
|
+
name: "av.trust",
|
|
46571
|
+
kind: "internal",
|
|
46572
|
+
startTime: now - opts.latencyMs,
|
|
46573
|
+
endTime: now,
|
|
46574
|
+
attributes,
|
|
46575
|
+
status
|
|
46576
|
+
};
|
|
46577
|
+
}
|
|
46578
|
+
function buildEvalRunSpan(opts) {
|
|
46579
|
+
const now = Date.now();
|
|
46580
|
+
const attributes = {
|
|
46581
|
+
"av.eval.scenario_id": opts.scenarioId,
|
|
46582
|
+
"av.eval.agent_id": opts.agentId,
|
|
46583
|
+
"av.eval.status": opts.status,
|
|
46584
|
+
"av.eval.latency_ms": opts.latencyMs
|
|
46585
|
+
};
|
|
46586
|
+
if (opts.scenarioName)
|
|
46587
|
+
attributes["av.eval.scenario_name"] = opts.scenarioName;
|
|
46588
|
+
if (opts.variationType)
|
|
46589
|
+
attributes["av.eval.variation_type"] = opts.variationType;
|
|
46590
|
+
if (opts.shiftMagnitude !== void 0)
|
|
46591
|
+
attributes["av.eval.shift_magnitude"] = opts.shiftMagnitude;
|
|
46592
|
+
if (opts.outcomeMatch !== void 0)
|
|
46593
|
+
attributes["av.eval.outcome_match"] = opts.outcomeMatch;
|
|
46594
|
+
if (opts.flagged !== void 0)
|
|
46595
|
+
attributes["av.eval.flagged"] = opts.flagged;
|
|
46596
|
+
if (opts.flagReason)
|
|
46597
|
+
attributes["av.eval.flag_reason"] = opts.flagReason;
|
|
46598
|
+
const isError = opts.status === "failed";
|
|
46599
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46600
|
+
return {
|
|
46601
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46602
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46603
|
+
parentSpanId: opts.parentSpanId,
|
|
46604
|
+
name: "av.eval.run",
|
|
46605
|
+
kind: "internal",
|
|
46606
|
+
startTime: now - opts.latencyMs,
|
|
46607
|
+
endTime: now,
|
|
46608
|
+
attributes,
|
|
46609
|
+
status
|
|
45721
46610
|
};
|
|
45722
46611
|
}
|
|
45723
46612
|
function buildTraceparent(span) {
|
|
45724
46613
|
return `00-${span.traceId}-${span.spanId}-01`;
|
|
45725
46614
|
}
|
|
46615
|
+
function parseTraceparent(header) {
|
|
46616
|
+
const parts = header.split("-");
|
|
46617
|
+
if (parts.length !== 4)
|
|
46618
|
+
return null;
|
|
46619
|
+
const [version2, traceId, parentId, traceFlags] = parts;
|
|
46620
|
+
if (!version2 || !traceId || !parentId || !traceFlags)
|
|
46621
|
+
return null;
|
|
46622
|
+
if (traceId.length !== 32 || parentId.length !== 16)
|
|
46623
|
+
return null;
|
|
46624
|
+
return { version: version2, traceId, parentId, traceFlags };
|
|
46625
|
+
}
|
|
46626
|
+
function spanToTraceContext(span, tracestate) {
|
|
46627
|
+
return {
|
|
46628
|
+
traceparent: buildTraceparent(span),
|
|
46629
|
+
tracestate: tracestate ?? `av=s:${span.spanId}`
|
|
46630
|
+
};
|
|
46631
|
+
}
|
|
46632
|
+
function propagateContext(incomingTraceparent) {
|
|
46633
|
+
const parsed = parseTraceparent(incomingTraceparent);
|
|
46634
|
+
if (!parsed)
|
|
46635
|
+
return null;
|
|
46636
|
+
return {
|
|
46637
|
+
traceId: parsed.traceId,
|
|
46638
|
+
parentSpanId: parsed.parentId,
|
|
46639
|
+
spanId: generateSpanId()
|
|
46640
|
+
};
|
|
46641
|
+
}
|
|
46642
|
+
function spanToW3CHeaders(span, tracestate) {
|
|
46643
|
+
return {
|
|
46644
|
+
traceparent: buildTraceparent(span),
|
|
46645
|
+
tracestate: tracestate ?? `av=s:${span.spanId}`
|
|
46646
|
+
};
|
|
46647
|
+
}
|
|
45726
46648
|
var init_telemetry = __esm({
|
|
45727
46649
|
"../crypto/dist/telemetry.js"() {
|
|
45728
46650
|
"use strict";
|
|
@@ -45893,6 +46815,29 @@ var init_telemetry_reporter = __esm({
|
|
|
45893
46815
|
});
|
|
45894
46816
|
|
|
45895
46817
|
// ../crypto/dist/backup.js
|
|
46818
|
+
async function generateBackupCode() {
|
|
46819
|
+
await libsodium_wrappers_default.ready;
|
|
46820
|
+
const bytes = libsodium_wrappers_default.randombytes_buf(13);
|
|
46821
|
+
let bits = 0n;
|
|
46822
|
+
for (const b2 of bytes) {
|
|
46823
|
+
bits = bits << 8n | BigInt(b2);
|
|
46824
|
+
}
|
|
46825
|
+
bits >>= 4n;
|
|
46826
|
+
let code = "";
|
|
46827
|
+
for (let i2 = 0; i2 < 20; i2++) {
|
|
46828
|
+
const idx = Number(bits & 0x1fn);
|
|
46829
|
+
code = CROCKFORD[idx] + code;
|
|
46830
|
+
bits >>= 5n;
|
|
46831
|
+
}
|
|
46832
|
+
return code;
|
|
46833
|
+
}
|
|
46834
|
+
function formatBackupCode(code) {
|
|
46835
|
+
const clean5 = code.replace(/[-\s]/g, "").toUpperCase();
|
|
46836
|
+
return clean5.match(/.{1,4}/g)?.join("-") ?? clean5;
|
|
46837
|
+
}
|
|
46838
|
+
function normalizeBackupCode(input) {
|
|
46839
|
+
return input.replace(/[-\s]/g, "").toUpperCase();
|
|
46840
|
+
}
|
|
45896
46841
|
async function deriveBackupKey(code, salt) {
|
|
45897
46842
|
await libsodium_wrappers_default.ready;
|
|
45898
46843
|
return libsodium_wrappers_default.crypto_pwhash(KEY_BYTES, code, salt, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, libsodium_wrappers_default.crypto_pwhash_ALG_ARGON2ID13);
|
|
@@ -45914,28 +46859,88 @@ async function encryptBackupWithKey(bundle, key, salt) {
|
|
|
45914
46859
|
result.set(ciphertext, SALT_BYTES + NONCE_BYTES);
|
|
45915
46860
|
return result;
|
|
45916
46861
|
}
|
|
46862
|
+
async function decryptBackup(encrypted, code) {
|
|
46863
|
+
await libsodium_wrappers_default.ready;
|
|
46864
|
+
const minLen = SALT_BYTES + NONCE_BYTES + libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_ABYTES;
|
|
46865
|
+
if (encrypted.length < minLen) {
|
|
46866
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46867
|
+
}
|
|
46868
|
+
const salt = encrypted.slice(0, SALT_BYTES);
|
|
46869
|
+
const nonce = encrypted.slice(SALT_BYTES, SALT_BYTES + NONCE_BYTES);
|
|
46870
|
+
const ciphertext = encrypted.slice(SALT_BYTES + NONCE_BYTES);
|
|
46871
|
+
const key = await deriveBackupKey(code, salt);
|
|
46872
|
+
let plaintext;
|
|
46873
|
+
try {
|
|
46874
|
+
plaintext = libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_decrypt(null, ciphertext, null, nonce, key);
|
|
46875
|
+
} catch {
|
|
46876
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46877
|
+
}
|
|
46878
|
+
let bundle;
|
|
46879
|
+
try {
|
|
46880
|
+
bundle = JSON.parse(libsodium_wrappers_default.to_string(plaintext));
|
|
46881
|
+
} catch {
|
|
46882
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46883
|
+
}
|
|
46884
|
+
if (bundle.version !== BACKUP_VERSION) {
|
|
46885
|
+
throw new Error(`Unsupported backup version: ${bundle.version}`);
|
|
46886
|
+
}
|
|
46887
|
+
return bundle;
|
|
46888
|
+
}
|
|
45917
46889
|
async function hashBackupCode(code) {
|
|
45918
46890
|
await libsodium_wrappers_default.ready;
|
|
45919
46891
|
return libsodium_wrappers_default.crypto_generichash(32, libsodium_wrappers_default.from_string(code));
|
|
45920
46892
|
}
|
|
45921
|
-
var ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, MAX_BACKUP_SIZE;
|
|
46893
|
+
var CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE;
|
|
45922
46894
|
var init_backup = __esm({
|
|
45923
46895
|
async "../crypto/dist/backup.js"() {
|
|
45924
46896
|
"use strict";
|
|
45925
46897
|
await init_libsodium_wrappers();
|
|
46898
|
+
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
45926
46899
|
ARGON2_OPSLIMIT = 2;
|
|
45927
46900
|
ARGON2_MEMLIMIT = 67108864;
|
|
45928
46901
|
SALT_BYTES = 16;
|
|
45929
46902
|
NONCE_BYTES = 24;
|
|
45930
46903
|
KEY_BYTES = 32;
|
|
46904
|
+
BACKUP_VERSION = 1;
|
|
45931
46905
|
MAX_BACKUP_SIZE = 512 * 1024;
|
|
45932
46906
|
}
|
|
45933
46907
|
});
|
|
45934
46908
|
|
|
45935
46909
|
// ../crypto/dist/approval.js
|
|
46910
|
+
async function createApprovalArtifact(content, privateKeyHex) {
|
|
46911
|
+
await libsodium_wrappers_default.ready;
|
|
46912
|
+
const sodium = libsodium_wrappers_default;
|
|
46913
|
+
const privateKey = sodium.from_hex(privateKeyHex);
|
|
46914
|
+
const publicKey = privateKey.slice(32);
|
|
46915
|
+
const message = canonicalize(content);
|
|
46916
|
+
const signatureBytes = sodium.crypto_sign_detached(message, privateKey);
|
|
46917
|
+
return {
|
|
46918
|
+
content,
|
|
46919
|
+
signature: sodium.to_hex(signatureBytes),
|
|
46920
|
+
signerPublicKey: sodium.to_hex(publicKey),
|
|
46921
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46922
|
+
version: 1
|
|
46923
|
+
};
|
|
46924
|
+
}
|
|
46925
|
+
async function verifyApprovalArtifact(artifact, expectedPublicKeyHex) {
|
|
46926
|
+
await libsodium_wrappers_default.ready;
|
|
46927
|
+
const sodium = libsodium_wrappers_default;
|
|
46928
|
+
if (expectedPublicKeyHex && artifact.signerPublicKey !== expectedPublicKeyHex) {
|
|
46929
|
+
return false;
|
|
46930
|
+
}
|
|
46931
|
+
try {
|
|
46932
|
+
const publicKey = sodium.from_hex(artifact.signerPublicKey);
|
|
46933
|
+
const signature = sodium.from_hex(artifact.signature);
|
|
46934
|
+
const message = canonicalize(artifact.content);
|
|
46935
|
+
return sodium.crypto_sign_verify_detached(signature, message, publicKey);
|
|
46936
|
+
} catch {
|
|
46937
|
+
return false;
|
|
46938
|
+
}
|
|
46939
|
+
}
|
|
45936
46940
|
var init_approval = __esm({
|
|
45937
46941
|
async "../crypto/dist/approval.js"() {
|
|
45938
46942
|
"use strict";
|
|
46943
|
+
await init_libsodium_wrappers();
|
|
45939
46944
|
await init_did();
|
|
45940
46945
|
}
|
|
45941
46946
|
});
|
|
@@ -54882,7 +55887,7 @@ function byteSwap32(arr) {
|
|
|
54882
55887
|
}
|
|
54883
55888
|
return arr;
|
|
54884
55889
|
}
|
|
54885
|
-
function
|
|
55890
|
+
function bytesToHex4(bytes) {
|
|
54886
55891
|
abytes3(bytes);
|
|
54887
55892
|
if (hasHexBuiltin)
|
|
54888
55893
|
return bytes.toHex();
|
|
@@ -54901,7 +55906,7 @@ function asciiToBase16(ch) {
|
|
|
54901
55906
|
return ch - (asciis.a - 10);
|
|
54902
55907
|
return;
|
|
54903
55908
|
}
|
|
54904
|
-
function
|
|
55909
|
+
function hexToBytes4(hex3) {
|
|
54905
55910
|
if (typeof hex3 !== "string")
|
|
54906
55911
|
throw new Error("hex string expected, got " + typeof hex3);
|
|
54907
55912
|
if (hasHexBuiltin)
|
|
@@ -55197,7 +56202,7 @@ var init_u642 = __esm({
|
|
|
55197
56202
|
});
|
|
55198
56203
|
|
|
55199
56204
|
// ../../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha2.js
|
|
55200
|
-
var SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384,
|
|
56205
|
+
var SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842;
|
|
55201
56206
|
var init_sha22 = __esm({
|
|
55202
56207
|
"../../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha2.js"() {
|
|
55203
56208
|
init_md2();
|
|
@@ -55558,7 +56563,7 @@ var init_sha22 = __esm({
|
|
|
55558
56563
|
this.Hl = SHA384_IV2[15] | 0;
|
|
55559
56564
|
}
|
|
55560
56565
|
};
|
|
55561
|
-
|
|
56566
|
+
sha2563 = /* @__PURE__ */ createHasher2(() => new SHA256());
|
|
55562
56567
|
sha5122 = /* @__PURE__ */ createHasher2(() => new SHA512());
|
|
55563
56568
|
sha3842 = /* @__PURE__ */ createHasher2(() => new SHA384());
|
|
55564
56569
|
}
|
|
@@ -55594,14 +56599,14 @@ function hexToNumber3(hex3) {
|
|
|
55594
56599
|
return hex3 === "" ? _0n2 : BigInt("0x" + hex3);
|
|
55595
56600
|
}
|
|
55596
56601
|
function bytesToNumberBE(bytes) {
|
|
55597
|
-
return hexToNumber3(
|
|
56602
|
+
return hexToNumber3(bytesToHex4(bytes));
|
|
55598
56603
|
}
|
|
55599
56604
|
function bytesToNumberLE2(bytes) {
|
|
55600
56605
|
abytes3(bytes);
|
|
55601
|
-
return hexToNumber3(
|
|
56606
|
+
return hexToNumber3(bytesToHex4(Uint8Array.from(bytes).reverse()));
|
|
55602
56607
|
}
|
|
55603
56608
|
function numberToBytesBE2(n2, len) {
|
|
55604
|
-
return
|
|
56609
|
+
return hexToBytes4(n2.toString(16).padStart(len * 2, "0"));
|
|
55605
56610
|
}
|
|
55606
56611
|
function numberToBytesLE2(n2, len) {
|
|
55607
56612
|
return numberToBytesBE2(n2, len).reverse();
|
|
@@ -55610,7 +56615,7 @@ function ensureBytes(title, hex3, expectedLength) {
|
|
|
55610
56615
|
let res;
|
|
55611
56616
|
if (typeof hex3 === "string") {
|
|
55612
56617
|
try {
|
|
55613
|
-
res =
|
|
56618
|
+
res = hexToBytes4(hex3);
|
|
55614
56619
|
} catch (e) {
|
|
55615
56620
|
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
55616
56621
|
}
|
|
@@ -56638,7 +57643,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
56638
57643
|
return bytes;
|
|
56639
57644
|
}
|
|
56640
57645
|
toHex() {
|
|
56641
|
-
return
|
|
57646
|
+
return bytesToHex4(this.toBytes());
|
|
56642
57647
|
}
|
|
56643
57648
|
toString() {
|
|
56644
57649
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -56910,7 +57915,7 @@ var init_edwards = __esm({
|
|
|
56910
57915
|
return this.ep.toAffine(invertedZ);
|
|
56911
57916
|
}
|
|
56912
57917
|
toHex() {
|
|
56913
|
-
return
|
|
57918
|
+
return bytesToHex4(this.toBytes());
|
|
56914
57919
|
}
|
|
56915
57920
|
toString() {
|
|
56916
57921
|
return this.toHex();
|
|
@@ -58711,7 +59716,7 @@ function weierstrassN(params, extraOpts = {}) {
|
|
|
58711
59716
|
return encodePoint(Point, this, isCompressed);
|
|
58712
59717
|
}
|
|
58713
59718
|
toHex(isCompressed = true) {
|
|
58714
|
-
return
|
|
59719
|
+
return bytesToHex4(this.toBytes(isCompressed));
|
|
58715
59720
|
}
|
|
58716
59721
|
toString() {
|
|
58717
59722
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -58995,7 +60000,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
58995
60000
|
return new Signature(Fn3.fromBytes(r2), Fn3.fromBytes(s2), recid);
|
|
58996
60001
|
}
|
|
58997
60002
|
static fromHex(hex3, format) {
|
|
58998
|
-
return this.fromBytes(
|
|
60003
|
+
return this.fromBytes(hexToBytes4(hex3), format);
|
|
58999
60004
|
}
|
|
59000
60005
|
addRecoveryBit(recovery) {
|
|
59001
60006
|
return new Signature(this.r, this.s, recovery);
|
|
@@ -59030,7 +60035,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59030
60035
|
toBytes(format = defaultSigOpts_format) {
|
|
59031
60036
|
validateSigFormat(format);
|
|
59032
60037
|
if (format === "der")
|
|
59033
|
-
return
|
|
60038
|
+
return hexToBytes4(DER.hexFromSig(this));
|
|
59034
60039
|
const r2 = Fn3.toBytes(this.r);
|
|
59035
60040
|
const s2 = Fn3.toBytes(this.s);
|
|
59036
60041
|
if (format === "recovered") {
|
|
@@ -59041,7 +60046,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59041
60046
|
return concatBytes2(r2, s2);
|
|
59042
60047
|
}
|
|
59043
60048
|
toHex(format) {
|
|
59044
|
-
return
|
|
60049
|
+
return bytesToHex4(this.toBytes(format));
|
|
59045
60050
|
}
|
|
59046
60051
|
// TODO: remove
|
|
59047
60052
|
assertValidity() {
|
|
@@ -59059,13 +60064,13 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59059
60064
|
return this.toBytes("der");
|
|
59060
60065
|
}
|
|
59061
60066
|
toDERHex() {
|
|
59062
|
-
return
|
|
60067
|
+
return bytesToHex4(this.toBytes("der"));
|
|
59063
60068
|
}
|
|
59064
60069
|
toCompactRawBytes() {
|
|
59065
60070
|
return this.toBytes("compact");
|
|
59066
60071
|
}
|
|
59067
60072
|
toCompactHex() {
|
|
59068
|
-
return
|
|
60073
|
+
return bytesToHex4(this.toBytes("compact"));
|
|
59069
60074
|
}
|
|
59070
60075
|
}
|
|
59071
60076
|
const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes) {
|
|
@@ -59444,7 +60449,7 @@ var init_nist = __esm({
|
|
|
59444
60449
|
Fp256 = Field(p256_CURVE.p);
|
|
59445
60450
|
Fp384 = Field(p384_CURVE.p);
|
|
59446
60451
|
Fp521 = Field(p521_CURVE.p);
|
|
59447
|
-
p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false },
|
|
60452
|
+
p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false }, sha2563);
|
|
59448
60453
|
p256_hasher = /* @__PURE__ */ (() => {
|
|
59449
60454
|
return createHasher3(p256.Point, createSWU(p256.Point, {
|
|
59450
60455
|
A: p256_CURVE.a,
|
|
@@ -59457,7 +60462,7 @@ var init_nist = __esm({
|
|
|
59457
60462
|
m: 1,
|
|
59458
60463
|
k: 128,
|
|
59459
60464
|
expand: "xmd",
|
|
59460
|
-
hash:
|
|
60465
|
+
hash: sha2563
|
|
59461
60466
|
});
|
|
59462
60467
|
})();
|
|
59463
60468
|
p384 = createCurve({ ...p384_CURVE, Fp: Fp384, lowS: false }, sha3842);
|
|
@@ -59965,7 +60970,7 @@ var init_u643 = __esm({
|
|
|
59965
60970
|
});
|
|
59966
60971
|
|
|
59967
60972
|
// ../crypto/node_modules/@noble/hashes/sha2.js
|
|
59968
|
-
var SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384,
|
|
60973
|
+
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;
|
|
59969
60974
|
var init_sha23 = __esm({
|
|
59970
60975
|
"../crypto/node_modules/@noble/hashes/sha2.js"() {
|
|
59971
60976
|
init_md3();
|
|
@@ -60338,7 +61343,7 @@ var init_sha23 = __esm({
|
|
|
60338
61343
|
super(48);
|
|
60339
61344
|
}
|
|
60340
61345
|
};
|
|
60341
|
-
|
|
61346
|
+
sha2564 = /* @__PURE__ */ createHasher4(
|
|
60342
61347
|
() => new _SHA256(),
|
|
60343
61348
|
/* @__PURE__ */ oidNist2(1)
|
|
60344
61349
|
);
|
|
@@ -60436,7 +61441,7 @@ function makeHashImpl2(h2) {
|
|
|
60436
61441
|
async digest(data) {
|
|
60437
61442
|
switch (h2) {
|
|
60438
61443
|
case "SHA-256":
|
|
60439
|
-
return
|
|
61444
|
+
return sha2564(data);
|
|
60440
61445
|
case "SHA-384":
|
|
60441
61446
|
return sha3843(data);
|
|
60442
61447
|
case "SHA-512":
|
|
@@ -60448,7 +61453,7 @@ function makeHashImpl2(h2) {
|
|
|
60448
61453
|
async mac(key, data) {
|
|
60449
61454
|
switch (h2) {
|
|
60450
61455
|
case "SHA-256":
|
|
60451
|
-
return hmac3(
|
|
61456
|
+
return hmac3(sha2564, key, data);
|
|
60452
61457
|
case "SHA-384":
|
|
60453
61458
|
return hmac3(sha3843, key, data);
|
|
60454
61459
|
case "SHA-512":
|
|
@@ -61615,6 +62620,92 @@ var init_mls_group = __esm({
|
|
|
61615
62620
|
});
|
|
61616
62621
|
|
|
61617
62622
|
// ../crypto/dist/index.js
|
|
62623
|
+
var dist_exports = {};
|
|
62624
|
+
__export(dist_exports, {
|
|
62625
|
+
AV_CREDENTIAL_CONTEXT: () => AV_CREDENTIAL_CONTEXT,
|
|
62626
|
+
CRYPTOSUITE: () => CRYPTOSUITE,
|
|
62627
|
+
DOMAIN_DID_DOCUMENT: () => DOMAIN_DID_DOCUMENT,
|
|
62628
|
+
DOMAIN_TRANSFER_ACCEPT: () => DOMAIN_TRANSFER_ACCEPT,
|
|
62629
|
+
DOMAIN_TRANSFER_INTENT: () => DOMAIN_TRANSFER_INTENT,
|
|
62630
|
+
DoubleRatchet: () => DoubleRatchet,
|
|
62631
|
+
MLSGroupManager: () => MLSGroupManager,
|
|
62632
|
+
ScanEngine: () => ScanEngine,
|
|
62633
|
+
TelemetryReporter: () => TelemetryReporter,
|
|
62634
|
+
VC_CONTEXT_V2: () => VC_CONTEXT_V2,
|
|
62635
|
+
base64ToBytes: () => base64ToBytes,
|
|
62636
|
+
buildA2aSpan: () => buildA2aSpan,
|
|
62637
|
+
buildActionSpan: () => buildActionSpan,
|
|
62638
|
+
buildAgentTrustCredential: () => buildAgentTrustCredential,
|
|
62639
|
+
buildAgentTrustReportCredential: () => buildAgentTrustReportCredential,
|
|
62640
|
+
buildCapabilitySpan: () => buildCapabilitySpan,
|
|
62641
|
+
buildDecisionSpan: () => buildDecisionSpan,
|
|
62642
|
+
buildDidDocument: () => buildDidDocument,
|
|
62643
|
+
buildEnrollmentSpan: () => buildEnrollmentSpan,
|
|
62644
|
+
buildErrorSpan: () => buildErrorSpan,
|
|
62645
|
+
buildEvalRunSpan: () => buildEvalRunSpan,
|
|
62646
|
+
buildEvalSpan: () => buildEvalSpan,
|
|
62647
|
+
buildForgeSpan: () => buildForgeSpan,
|
|
62648
|
+
buildHttpSpan: () => buildHttpSpan,
|
|
62649
|
+
buildLlmSpan: () => buildLlmSpan,
|
|
62650
|
+
buildNavSpan: () => buildNavSpan,
|
|
62651
|
+
buildPerformanceRecord: () => buildPerformanceRecord,
|
|
62652
|
+
buildPolicyViolationSpan: () => buildPolicyViolationSpan,
|
|
62653
|
+
buildResyncSpan: () => buildResyncSpan,
|
|
62654
|
+
buildRoomSpan: () => buildRoomSpan,
|
|
62655
|
+
buildScanSpan: () => buildScanSpan,
|
|
62656
|
+
buildSkillAttestation: () => buildSkillAttestation,
|
|
62657
|
+
buildSkillInvocationSpan: () => buildSkillInvocationSpan,
|
|
62658
|
+
buildTaskSpan: () => buildTaskSpan,
|
|
62659
|
+
buildToolSpan: () => buildToolSpan,
|
|
62660
|
+
buildTraceparent: () => buildTraceparent,
|
|
62661
|
+
buildTrustSpan: () => buildTrustSpan,
|
|
62662
|
+
buildVerifiablePresentation: () => buildVerifiablePresentation,
|
|
62663
|
+
buildWorkspaceSpan: () => buildWorkspaceSpan,
|
|
62664
|
+
bytesToBase64: () => bytesToBase64,
|
|
62665
|
+
bytesToHex: () => bytesToHex2,
|
|
62666
|
+
canonicalize: () => canonicalize,
|
|
62667
|
+
computeDidHash: () => computeDidHash,
|
|
62668
|
+
computeFileDigest: () => computeFileDigest,
|
|
62669
|
+
computeFingerprint: () => computeFingerprint,
|
|
62670
|
+
createApprovalArtifact: () => createApprovalArtifact,
|
|
62671
|
+
createProofOfPossession: () => createProofOfPossession,
|
|
62672
|
+
decryptBackup: () => decryptBackup,
|
|
62673
|
+
decryptFile: () => decryptFile,
|
|
62674
|
+
deriveBackupKey: () => deriveBackupKey,
|
|
62675
|
+
encryptBackup: () => encryptBackup,
|
|
62676
|
+
encryptBackupWithKey: () => encryptBackupWithKey,
|
|
62677
|
+
encryptFile: () => encryptFile,
|
|
62678
|
+
encryptedMessageToHexTransport: () => encryptedMessageToHexTransport,
|
|
62679
|
+
encryptedMessageToTransport: () => encryptedMessageToTransport,
|
|
62680
|
+
encryptedMessageToTransportV2: () => encryptedMessageToTransportV2,
|
|
62681
|
+
encryptedMessageToTransportV2Full: () => encryptedMessageToTransportV2Full,
|
|
62682
|
+
formatBackupCode: () => formatBackupCode,
|
|
62683
|
+
generateBackupCode: () => generateBackupCode,
|
|
62684
|
+
generateEphemeralKeypair: () => generateEphemeralKeypair,
|
|
62685
|
+
generateIdentityKeypair: () => generateIdentityKeypair,
|
|
62686
|
+
hashBackupCode: () => hashBackupCode,
|
|
62687
|
+
hexToBytes: () => hexToBytes2,
|
|
62688
|
+
hexTransportToEncryptedMessage: () => hexTransportToEncryptedMessage,
|
|
62689
|
+
issueCredential: () => issueCredential,
|
|
62690
|
+
multibaseToPublicKey: () => multibaseToPublicKey,
|
|
62691
|
+
normalizeBackupCode: () => normalizeBackupCode,
|
|
62692
|
+
parseTraceparent: () => parseTraceparent,
|
|
62693
|
+
performX3DH: () => performX3DH,
|
|
62694
|
+
presentCredentials: () => presentCredentials,
|
|
62695
|
+
propagateContext: () => propagateContext,
|
|
62696
|
+
publicKeyToMultibase: () => publicKeyToMultibase,
|
|
62697
|
+
signDocument: () => signDocument,
|
|
62698
|
+
signWithDataIntegrity: () => signWithDataIntegrity,
|
|
62699
|
+
spanToTraceContext: () => spanToTraceContext,
|
|
62700
|
+
spanToW3CHeaders: () => spanToW3CHeaders,
|
|
62701
|
+
transportToEncryptedMessage: () => transportToEncryptedMessage,
|
|
62702
|
+
transportV2ToEncryptedMessage: () => transportV2ToEncryptedMessage,
|
|
62703
|
+
verifyApprovalArtifact: () => verifyApprovalArtifact,
|
|
62704
|
+
verifyDataIntegrity: () => verifyDataIntegrity,
|
|
62705
|
+
verifyDocumentSignature: () => verifyDocumentSignature,
|
|
62706
|
+
verifyMerkleProof: () => verifyMerkleProof,
|
|
62707
|
+
verifyProofOfPossession: () => verifyProofOfPossession
|
|
62708
|
+
});
|
|
61618
62709
|
var init_dist = __esm({
|
|
61619
62710
|
async "../crypto/dist/index.js"() {
|
|
61620
62711
|
"use strict";
|
|
@@ -61905,7 +62996,7 @@ async function uploadBackupToServer(state, backupCode, apiUrl2, deviceJwt) {
|
|
|
61905
62996
|
},
|
|
61906
62997
|
body: JSON.stringify({
|
|
61907
62998
|
backup_blob: bytesToBase64(encrypted),
|
|
61908
|
-
backup_code_hash:
|
|
62999
|
+
backup_code_hash: bytesToHex2(codeHash)
|
|
61909
63000
|
})
|
|
61910
63001
|
});
|
|
61911
63002
|
if (!resp.ok) {
|
|
@@ -62549,6 +63640,8 @@ var init_channel = __esm({
|
|
|
62549
63640
|
_mlsGroups = /* @__PURE__ */ new Map();
|
|
62550
63641
|
/** Cached MLS KeyPackage bundle for this device (regenerated on each connect). */
|
|
62551
63642
|
_mlsKeyPackage = null;
|
|
63643
|
+
/** Pending KeyPackage bundle from request-Welcome flow (used by _handleMlsWelcome). */
|
|
63644
|
+
_pendingMlsKpBundle;
|
|
62552
63645
|
/** In-memory credential store for renter-provided credentials (never persisted). */
|
|
62553
63646
|
_credentialStore = new CredentialStore();
|
|
62554
63647
|
/** Dedup buffer for A2A message IDs (prevents double-delivery via direct + Redis) */
|
|
@@ -62647,6 +63740,24 @@ var init_channel = __esm({
|
|
|
62647
63740
|
if (this._persisted.seenA2AMessageIds) {
|
|
62648
63741
|
this._a2aSeenMessageIds = new Set(this._persisted.seenA2AMessageIds.slice(-_SecureChannel.A2A_SEEN_MAX));
|
|
62649
63742
|
}
|
|
63743
|
+
if (this._persisted?.rooms) {
|
|
63744
|
+
const roomConvIds = /* @__PURE__ */ new Set();
|
|
63745
|
+
for (const room of Object.values(this._persisted.rooms)) {
|
|
63746
|
+
for (const cid of room.conversationIds || []) {
|
|
63747
|
+
roomConvIds.add(cid);
|
|
63748
|
+
}
|
|
63749
|
+
}
|
|
63750
|
+
let cleanedCount = 0;
|
|
63751
|
+
for (const cid of roomConvIds) {
|
|
63752
|
+
if (this._persisted.sessions[cid]) {
|
|
63753
|
+
delete this._persisted.sessions[cid];
|
|
63754
|
+
cleanedCount++;
|
|
63755
|
+
}
|
|
63756
|
+
}
|
|
63757
|
+
if (cleanedCount > 0) {
|
|
63758
|
+
console.log(`[SecureChannel] Cleaned ${cleanedCount} stale DR room sessions`);
|
|
63759
|
+
}
|
|
63760
|
+
}
|
|
62650
63761
|
for (const [convId, sessionData] of Object.entries(
|
|
62651
63762
|
this._persisted.sessions
|
|
62652
63763
|
)) {
|
|
@@ -63019,89 +64130,21 @@ var init_channel = __esm({
|
|
|
63019
64130
|
}
|
|
63020
64131
|
// --- Multi-agent room methods ---
|
|
63021
64132
|
/**
|
|
63022
|
-
* Join a room by
|
|
63023
|
-
*
|
|
64133
|
+
* Join a room by collecting pairwise conversation IDs involving this device.
|
|
64134
|
+
* Encryption is handled by MLS group operations, not per-member DR sessions.
|
|
63024
64135
|
*/
|
|
63025
64136
|
async joinRoom(roomData) {
|
|
63026
64137
|
if (!this._persisted) {
|
|
63027
64138
|
throw new Error("Channel not initialized");
|
|
63028
64139
|
}
|
|
63029
64140
|
await libsodium_wrappers_default.ready;
|
|
63030
|
-
if (roomData.forceRekey) {
|
|
63031
|
-
let cleared = 0;
|
|
63032
|
-
const existingRoom = this._persisted.rooms?.[roomData.roomId];
|
|
63033
|
-
if (existingRoom) {
|
|
63034
|
-
for (const convId of existingRoom.conversationIds) {
|
|
63035
|
-
if (this._sessions.has(convId)) {
|
|
63036
|
-
this._sessions.delete(convId);
|
|
63037
|
-
cleared++;
|
|
63038
|
-
}
|
|
63039
|
-
delete this._persisted.sessions[convId];
|
|
63040
|
-
}
|
|
63041
|
-
}
|
|
63042
|
-
if (this._persisted) {
|
|
63043
|
-
this._persisted.lastMessageTimestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
63044
|
-
}
|
|
63045
|
-
console.log(
|
|
63046
|
-
`[SecureChannel] Force rekey: cleared ${cleared} sessions for room ${roomData.roomId.slice(0, 8)}...`
|
|
63047
|
-
);
|
|
63048
|
-
}
|
|
63049
|
-
const identity = this._persisted.identityKeypair;
|
|
63050
|
-
const ephemeral = this._persisted.ephemeralKeypair;
|
|
63051
64141
|
const myDeviceId = this._deviceId;
|
|
63052
64142
|
const conversationIds = [];
|
|
63053
64143
|
for (const conv of roomData.conversations) {
|
|
63054
64144
|
if (conv.participantA !== myDeviceId && conv.participantB !== myDeviceId) {
|
|
63055
64145
|
continue;
|
|
63056
64146
|
}
|
|
63057
|
-
if (this._sessions.has(conv.id)) {
|
|
63058
|
-
conversationIds.push(conv.id);
|
|
63059
|
-
continue;
|
|
63060
|
-
}
|
|
63061
|
-
const otherDeviceId = conv.participantA === myDeviceId ? conv.participantB : conv.participantA;
|
|
63062
|
-
const otherMember = roomData.members.find((m2) => m2.deviceId === otherDeviceId);
|
|
63063
|
-
if (!otherMember?.identityPublicKey) {
|
|
63064
|
-
console.warn(
|
|
63065
|
-
`[SecureChannel] No public key for member ${otherDeviceId.slice(0, 8)}..., skipping`
|
|
63066
|
-
);
|
|
63067
|
-
continue;
|
|
63068
|
-
}
|
|
63069
|
-
const isInitiator = myDeviceId < otherDeviceId;
|
|
63070
|
-
const theirEphKey = otherMember.ephemeralPublicKey ?? otherMember.identityPublicKey;
|
|
63071
|
-
const sharedSecret = performX3DH({
|
|
63072
|
-
myIdentityPrivate: hexToBytes(identity.privateKey),
|
|
63073
|
-
myEphemeralPrivate: hexToBytes(ephemeral.privateKey),
|
|
63074
|
-
theirIdentityPublic: hexToBytes(otherMember.identityPublicKey),
|
|
63075
|
-
theirEphemeralPublic: hexToBytes(theirEphKey),
|
|
63076
|
-
isInitiator
|
|
63077
|
-
});
|
|
63078
|
-
const peerIdentityPub = hexToBytes(otherMember.identityPublicKey);
|
|
63079
|
-
const ratchet = isInitiator ? DoubleRatchet.initSender(sharedSecret, {
|
|
63080
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
63081
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
63082
|
-
keyType: "ed25519"
|
|
63083
|
-
}, peerIdentityPub) : DoubleRatchet.initReceiver(sharedSecret, {
|
|
63084
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
63085
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
63086
|
-
keyType: "ed25519"
|
|
63087
|
-
}, peerIdentityPub);
|
|
63088
|
-
this._sessions.set(conv.id, {
|
|
63089
|
-
ownerDeviceId: otherDeviceId,
|
|
63090
|
-
ratchet,
|
|
63091
|
-
activated: isInitiator,
|
|
63092
|
-
// initiator can send immediately
|
|
63093
|
-
epoch: 1
|
|
63094
|
-
});
|
|
63095
|
-
this._persisted.sessions[conv.id] = {
|
|
63096
|
-
ownerDeviceId: otherDeviceId,
|
|
63097
|
-
ratchetState: ratchet.serialize(),
|
|
63098
|
-
activated: isInitiator,
|
|
63099
|
-
epoch: 1
|
|
63100
|
-
};
|
|
63101
64147
|
conversationIds.push(conv.id);
|
|
63102
|
-
console.log(
|
|
63103
|
-
`[SecureChannel] Room session initialized: conv ${conv.id.slice(0, 8)}... with ${otherDeviceId.slice(0, 8)}... (initiator=${isInitiator})`
|
|
63104
|
-
);
|
|
63105
64148
|
}
|
|
63106
64149
|
if (!this._persisted.rooms) {
|
|
63107
64150
|
this._persisted.rooms = {};
|
|
@@ -63197,68 +64240,15 @@ var init_channel = __esm({
|
|
|
63197
64240
|
}
|
|
63198
64241
|
return;
|
|
63199
64242
|
} catch (mlsErr) {
|
|
63200
|
-
|
|
63201
|
-
|
|
63202
|
-
|
|
63203
|
-
}
|
|
63204
|
-
const recipients = [];
|
|
63205
|
-
for (const convId of room.conversationIds) {
|
|
63206
|
-
const session = this._sessions.get(convId);
|
|
63207
|
-
if (!session) {
|
|
63208
|
-
console.warn(`[SecureChannel] No session for room conv ${convId.slice(0, 8)}..., skipping`);
|
|
63209
|
-
continue;
|
|
63210
|
-
}
|
|
63211
|
-
const encrypted = session.ratchet.encrypt(plaintext);
|
|
63212
|
-
const transport = encryptedMessageToTransport(encrypted);
|
|
63213
|
-
recipients.push({
|
|
63214
|
-
device_id: session.ownerDeviceId,
|
|
63215
|
-
header_blob: transport.header_blob,
|
|
63216
|
-
ciphertext: transport.ciphertext
|
|
63217
|
-
});
|
|
63218
|
-
}
|
|
63219
|
-
if (recipients.length === 0) {
|
|
63220
|
-
throw new Error("No active sessions in room");
|
|
63221
|
-
}
|
|
63222
|
-
await this._persistState();
|
|
63223
|
-
if (this._state === "ready" && this._ws) {
|
|
63224
|
-
this._ws.send(
|
|
63225
|
-
JSON.stringify({
|
|
63226
|
-
event: "room_message",
|
|
63227
|
-
data: {
|
|
63228
|
-
room_id: roomId,
|
|
63229
|
-
recipients,
|
|
63230
|
-
message_type: messageType,
|
|
63231
|
-
priority: opts?.priority ?? "normal",
|
|
63232
|
-
metadata: opts?.metadata
|
|
63233
|
-
}
|
|
63234
|
-
})
|
|
63235
|
-
);
|
|
63236
|
-
} else {
|
|
63237
|
-
try {
|
|
63238
|
-
const res = await fetch(
|
|
63239
|
-
`${this.config.apiUrl}/api/v1/rooms/${roomId}/messages`,
|
|
63240
|
-
{
|
|
63241
|
-
method: "POST",
|
|
63242
|
-
headers: {
|
|
63243
|
-
"Content-Type": "application/json",
|
|
63244
|
-
Authorization: `Bearer ${this._deviceJwt}`
|
|
63245
|
-
},
|
|
63246
|
-
body: JSON.stringify({
|
|
63247
|
-
recipients,
|
|
63248
|
-
message_type: messageType,
|
|
63249
|
-
priority: opts?.priority ?? "normal",
|
|
63250
|
-
metadata: opts?.metadata
|
|
63251
|
-
})
|
|
63252
|
-
}
|
|
63253
|
-
);
|
|
63254
|
-
if (!res.ok) {
|
|
63255
|
-
const detail = await res.text();
|
|
63256
|
-
throw new Error(`Room message failed (${res.status}): ${detail}`);
|
|
64243
|
+
throw new Error(
|
|
64244
|
+
`MLS encrypt failed for room ${roomId.slice(0, 8)}... \u2014 MLS group must be initialized before sending. Error: ${mlsErr}`
|
|
64245
|
+
);
|
|
63257
64246
|
}
|
|
63258
|
-
} catch (err) {
|
|
63259
|
-
throw new Error(`Failed to send room message: ${err}`);
|
|
63260
64247
|
}
|
|
63261
64248
|
}
|
|
64249
|
+
throw new Error(
|
|
64250
|
+
`Room ${roomId.slice(0, 8)}... has no initialized MLS group. MLS initialization must complete before messages can be sent.`
|
|
64251
|
+
);
|
|
63262
64252
|
}
|
|
63263
64253
|
/**
|
|
63264
64254
|
* Leave a room: remove sessions and persisted room state.
|
|
@@ -64088,9 +65078,9 @@ var init_channel = __esm({
|
|
|
64088
65078
|
const result = await enrollDevice(
|
|
64089
65079
|
this.config.apiUrl,
|
|
64090
65080
|
this.config.inviteToken,
|
|
64091
|
-
|
|
64092
|
-
|
|
64093
|
-
|
|
65081
|
+
bytesToHex2(identity.publicKey),
|
|
65082
|
+
bytesToHex2(ephemeral.publicKey),
|
|
65083
|
+
bytesToHex2(proof),
|
|
64094
65084
|
this.config.platform
|
|
64095
65085
|
);
|
|
64096
65086
|
this._deviceId = result.device_id;
|
|
@@ -64104,12 +65094,12 @@ var init_channel = __esm({
|
|
|
64104
65094
|
sessions: {},
|
|
64105
65095
|
// populated after activation
|
|
64106
65096
|
identityKeypair: {
|
|
64107
|
-
publicKey:
|
|
64108
|
-
privateKey:
|
|
65097
|
+
publicKey: bytesToHex2(identity.publicKey),
|
|
65098
|
+
privateKey: bytesToHex2(identity.privateKey)
|
|
64109
65099
|
},
|
|
64110
65100
|
ephemeralKeypair: {
|
|
64111
|
-
publicKey:
|
|
64112
|
-
privateKey:
|
|
65101
|
+
publicKey: bytesToHex2(ephemeral.publicKey),
|
|
65102
|
+
privateKey: bytesToHex2(ephemeral.privateKey)
|
|
64113
65103
|
},
|
|
64114
65104
|
fingerprint: result.fingerprint,
|
|
64115
65105
|
messageHistory: []
|
|
@@ -64172,17 +65162,17 @@ var init_channel = __esm({
|
|
|
64172
65162
|
const ownerIdentityKey = conv.owner_identity_public_key || result.owner_identity_public_key;
|
|
64173
65163
|
const ownerEphemeralKey = conv.owner_ephemeral_public_key || result.owner_ephemeral_public_key || ownerIdentityKey;
|
|
64174
65164
|
const sharedSecret = performX3DH({
|
|
64175
|
-
myIdentityPrivate:
|
|
64176
|
-
myEphemeralPrivate:
|
|
64177
|
-
theirIdentityPublic:
|
|
64178
|
-
theirEphemeralPublic:
|
|
65165
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
65166
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
65167
|
+
theirIdentityPublic: hexToBytes2(ownerIdentityKey),
|
|
65168
|
+
theirEphemeralPublic: hexToBytes2(ownerEphemeralKey),
|
|
64179
65169
|
isInitiator: false
|
|
64180
65170
|
});
|
|
64181
65171
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
64182
|
-
publicKey:
|
|
64183
|
-
privateKey:
|
|
65172
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
65173
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
64184
65174
|
keyType: "ed25519"
|
|
64185
|
-
},
|
|
65175
|
+
}, hexToBytes2(ownerIdentityKey));
|
|
64186
65176
|
this._sessions.set(conv.conversation_id, {
|
|
64187
65177
|
ownerDeviceId: conv.owner_device_id,
|
|
64188
65178
|
ratchet,
|
|
@@ -65308,19 +66298,19 @@ ${messageText}`;
|
|
|
65308
66298
|
const identity = this._persisted.identityKeypair;
|
|
65309
66299
|
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65310
66300
|
const sharedSecret = performX3DH({
|
|
65311
|
-
myIdentityPrivate:
|
|
65312
|
-
myEphemeralPrivate:
|
|
65313
|
-
theirIdentityPublic:
|
|
65314
|
-
theirEphemeralPublic:
|
|
66301
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
66302
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
66303
|
+
theirIdentityPublic: hexToBytes2(event.owner_identity_public_key),
|
|
66304
|
+
theirEphemeralPublic: hexToBytes2(
|
|
65315
66305
|
event.owner_ephemeral_public_key ?? event.owner_identity_public_key
|
|
65316
66306
|
),
|
|
65317
66307
|
isInitiator: false
|
|
65318
66308
|
});
|
|
65319
66309
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
65320
|
-
publicKey:
|
|
65321
|
-
privateKey:
|
|
66310
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
66311
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
65322
66312
|
keyType: "ed25519"
|
|
65323
|
-
},
|
|
66313
|
+
}, hexToBytes2(event.owner_identity_public_key));
|
|
65324
66314
|
this._sessions.set(event.conversation_id, {
|
|
65325
66315
|
ownerDeviceId: event.owner_device_id,
|
|
65326
66316
|
ratchet,
|
|
@@ -65367,17 +66357,17 @@ ${messageText}`;
|
|
|
65367
66357
|
const identity = this._persisted.identityKeypair;
|
|
65368
66358
|
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65369
66359
|
const sharedSecret = performX3DH({
|
|
65370
|
-
myIdentityPrivate:
|
|
65371
|
-
myEphemeralPrivate:
|
|
65372
|
-
theirIdentityPublic:
|
|
65373
|
-
theirEphemeralPublic:
|
|
66360
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
66361
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
66362
|
+
theirIdentityPublic: hexToBytes2(data.identity_public_key),
|
|
66363
|
+
theirEphemeralPublic: hexToBytes2(data.ephemeral_public_key),
|
|
65374
66364
|
isInitiator: false
|
|
65375
66365
|
});
|
|
65376
66366
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
65377
|
-
publicKey:
|
|
65378
|
-
privateKey:
|
|
66367
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
66368
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
65379
66369
|
keyType: "ed25519"
|
|
65380
|
-
},
|
|
66370
|
+
}, hexToBytes2(data.identity_public_key));
|
|
65381
66371
|
const existingSession = this._sessions.get(convId);
|
|
65382
66372
|
const existingPersisted = this._persisted.sessions[convId];
|
|
65383
66373
|
const ownerDeviceId = data.sender_device_id ?? existingSession?.ownerDeviceId ?? "";
|
|
@@ -65418,250 +66408,8 @@ ${messageText}`;
|
|
|
65418
66408
|
this.emit("error", err);
|
|
65419
66409
|
}
|
|
65420
66410
|
}
|
|
65421
|
-
|
|
65422
|
-
|
|
65423
|
-
* Shared by all room ratchet failure paths to avoid code duplication.
|
|
65424
|
-
*/
|
|
65425
|
-
_sendRoomResyncIfCooled(convId, reason, session) {
|
|
65426
|
-
const RESYNC_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
65427
|
-
const lastResync = this._lastResyncRequest.get(convId) ?? 0;
|
|
65428
|
-
if (Date.now() - lastResync > RESYNC_COOLDOWN_MS && this._ws && this._persisted) {
|
|
65429
|
-
this._lastResyncRequest.set(convId, Date.now());
|
|
65430
|
-
this._ws.send(
|
|
65431
|
-
JSON.stringify({
|
|
65432
|
-
event: "resync_request",
|
|
65433
|
-
data: {
|
|
65434
|
-
conversation_id: convId,
|
|
65435
|
-
reason,
|
|
65436
|
-
identity_public_key: this._persisted.identityKeypair.publicKey,
|
|
65437
|
-
ephemeral_public_key: this._persisted.ephemeralKeypair.publicKey,
|
|
65438
|
-
epoch: session?.epoch
|
|
65439
|
-
}
|
|
65440
|
-
})
|
|
65441
|
-
);
|
|
65442
|
-
console.log(
|
|
65443
|
-
`[SecureChannel] Room resync requested for conv ${convId.slice(0, 8)} (${reason})`
|
|
65444
|
-
);
|
|
65445
|
-
}
|
|
65446
|
-
}
|
|
65447
|
-
/**
|
|
65448
|
-
* Handle an incoming room message (pairwise path — used by sync replay and pairwise room fallback).
|
|
65449
|
-
* Finds the pairwise conversation for the sender, decrypts, and emits a room_message event.
|
|
65450
|
-
*/
|
|
65451
|
-
async _handleRoomMessage(msgData) {
|
|
65452
|
-
if (msgData.sender_device_id === this._deviceId) return;
|
|
65453
|
-
this._lastInboundRoomId = msgData.room_id;
|
|
65454
|
-
const convId = msgData.conversation_id ?? this._findConversationForSender(msgData.sender_device_id, msgData.room_id);
|
|
65455
|
-
if (!convId) {
|
|
65456
|
-
console.warn(
|
|
65457
|
-
`[SecureChannel] No conversation found for sender ${msgData.sender_device_id.slice(0, 8)}... in room ${msgData.room_id}`
|
|
65458
|
-
);
|
|
65459
|
-
return;
|
|
65460
|
-
}
|
|
65461
|
-
let session = this._sessions.get(convId);
|
|
65462
|
-
if (!session) {
|
|
65463
|
-
console.warn(
|
|
65464
|
-
`[SecureChannel] No session for room conv ${convId.slice(0, 8)}..., fetching room data`
|
|
65465
|
-
);
|
|
65466
|
-
try {
|
|
65467
|
-
const roomRes = await fetch(
|
|
65468
|
-
`${this.config.apiUrl}/api/v1/rooms/${msgData.room_id}`,
|
|
65469
|
-
{
|
|
65470
|
-
headers: {
|
|
65471
|
-
Authorization: `Bearer ${this._persisted.deviceJwt}`
|
|
65472
|
-
}
|
|
65473
|
-
}
|
|
65474
|
-
);
|
|
65475
|
-
if (roomRes.ok) {
|
|
65476
|
-
const roomData = await roomRes.json();
|
|
65477
|
-
await this.joinRoom({
|
|
65478
|
-
roomId: roomData.id,
|
|
65479
|
-
name: roomData.name,
|
|
65480
|
-
members: (roomData.members || []).map((m2) => ({
|
|
65481
|
-
deviceId: m2.device_id,
|
|
65482
|
-
entityType: m2.entity_type,
|
|
65483
|
-
displayName: m2.display_name,
|
|
65484
|
-
identityPublicKey: m2.identity_public_key,
|
|
65485
|
-
ephemeralPublicKey: m2.ephemeral_public_key
|
|
65486
|
-
})),
|
|
65487
|
-
conversations: (roomData.conversations || []).map((c2) => ({
|
|
65488
|
-
id: c2.id,
|
|
65489
|
-
participantA: c2.participant_a,
|
|
65490
|
-
participantB: c2.participant_b
|
|
65491
|
-
}))
|
|
65492
|
-
});
|
|
65493
|
-
session = this._sessions.get(convId);
|
|
65494
|
-
}
|
|
65495
|
-
} catch (fetchErr) {
|
|
65496
|
-
console.error(
|
|
65497
|
-
`[SecureChannel] Failed to fetch room data for ${msgData.room_id}:`,
|
|
65498
|
-
fetchErr
|
|
65499
|
-
);
|
|
65500
|
-
}
|
|
65501
|
-
if (!session) {
|
|
65502
|
-
console.warn(
|
|
65503
|
-
`[SecureChannel] Still no session for room conv ${convId.slice(0, 8)}... after refresh, skipping`
|
|
65504
|
-
);
|
|
65505
|
-
return;
|
|
65506
|
-
}
|
|
65507
|
-
}
|
|
65508
|
-
const encrypted = transportToEncryptedMessage({
|
|
65509
|
-
header_blob: msgData.header_blob,
|
|
65510
|
-
ciphertext: msgData.ciphertext
|
|
65511
|
-
});
|
|
65512
|
-
let plaintext;
|
|
65513
|
-
const ratchetSnapshot = session.ratchet.serialize();
|
|
65514
|
-
try {
|
|
65515
|
-
plaintext = session.ratchet.decrypt(encrypted);
|
|
65516
|
-
} catch (decryptErr) {
|
|
65517
|
-
try {
|
|
65518
|
-
session.ratchet = DoubleRatchet.deserialize(ratchetSnapshot);
|
|
65519
|
-
} catch {
|
|
65520
|
-
}
|
|
65521
|
-
console.warn(
|
|
65522
|
-
`[SecureChannel] Room decrypt failed for conv ${convId.slice(0, 8)}...: ${String(decryptErr)}, re-initializing ratchet`
|
|
65523
|
-
);
|
|
65524
|
-
try {
|
|
65525
|
-
const roomEntry = this._persisted?.rooms ? Object.values(this._persisted.rooms).find(
|
|
65526
|
-
(r2) => r2.conversationIds.includes(convId)
|
|
65527
|
-
) : null;
|
|
65528
|
-
if (!roomEntry) throw new Error("Room not found for conversation");
|
|
65529
|
-
const otherMember = roomEntry.members.find(
|
|
65530
|
-
(m2) => m2.deviceId === msgData.sender_device_id
|
|
65531
|
-
);
|
|
65532
|
-
if (!otherMember?.identityPublicKey) throw new Error("No key for sender");
|
|
65533
|
-
const isInitiator = this._deviceId < msgData.sender_device_id;
|
|
65534
|
-
const identity = this._persisted.identityKeypair;
|
|
65535
|
-
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65536
|
-
const sharedSecret = performX3DH({
|
|
65537
|
-
myIdentityPrivate: hexToBytes(identity.privateKey),
|
|
65538
|
-
myEphemeralPrivate: hexToBytes(ephemeral.privateKey),
|
|
65539
|
-
theirIdentityPublic: hexToBytes(otherMember.identityPublicKey),
|
|
65540
|
-
theirEphemeralPublic: hexToBytes(
|
|
65541
|
-
otherMember.ephemeralPublicKey ?? otherMember.identityPublicKey
|
|
65542
|
-
),
|
|
65543
|
-
isInitiator
|
|
65544
|
-
});
|
|
65545
|
-
const peerIdPub = hexToBytes(otherMember.identityPublicKey);
|
|
65546
|
-
const newRatchet = isInitiator ? DoubleRatchet.initSender(sharedSecret, {
|
|
65547
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
65548
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
65549
|
-
keyType: "ed25519"
|
|
65550
|
-
}, peerIdPub) : DoubleRatchet.initReceiver(sharedSecret, {
|
|
65551
|
-
publicKey: hexToBytes(identity.publicKey),
|
|
65552
|
-
privateKey: hexToBytes(identity.privateKey),
|
|
65553
|
-
keyType: "ed25519"
|
|
65554
|
-
}, peerIdPub);
|
|
65555
|
-
session.ratchet = newRatchet;
|
|
65556
|
-
session.activated = false;
|
|
65557
|
-
this._persisted.sessions[convId] = {
|
|
65558
|
-
ownerDeviceId: session.ownerDeviceId,
|
|
65559
|
-
ratchetState: newRatchet.serialize(),
|
|
65560
|
-
activated: false
|
|
65561
|
-
};
|
|
65562
|
-
await this._persistState();
|
|
65563
|
-
console.log(
|
|
65564
|
-
`[SecureChannel] Room ratchet re-initialized for conv ${convId.slice(0, 8)}...`
|
|
65565
|
-
);
|
|
65566
|
-
const incomingMsgNum = encrypted.header.messageNumber;
|
|
65567
|
-
if (incomingMsgNum <= 5) {
|
|
65568
|
-
try {
|
|
65569
|
-
plaintext = session.ratchet.decrypt(encrypted);
|
|
65570
|
-
session.activated = true;
|
|
65571
|
-
if (this._persisted.sessions[convId]) {
|
|
65572
|
-
this._persisted.sessions[convId].activated = true;
|
|
65573
|
-
}
|
|
65574
|
-
await this._persistState();
|
|
65575
|
-
console.log(
|
|
65576
|
-
`[SecureChannel] Room session ${convId.slice(0, 8)}... re-activated after ratchet re-init`
|
|
65577
|
-
);
|
|
65578
|
-
} catch (retryErr) {
|
|
65579
|
-
console.warn(
|
|
65580
|
-
`[SecureChannel] Room re-init retry failed for conv ${convId.slice(0, 8)} (msgNum=${incomingMsgNum}):`,
|
|
65581
|
-
retryErr
|
|
65582
|
-
);
|
|
65583
|
-
this._sendRoomResyncIfCooled(convId, "room_reinit_retry_failed", session);
|
|
65584
|
-
return;
|
|
65585
|
-
}
|
|
65586
|
-
} else {
|
|
65587
|
-
console.log(
|
|
65588
|
-
`[SecureChannel] Room re-init: skipping message with msgNum=${incomingMsgNum} for conv ${convId.slice(0, 8)} (too far ahead for fresh ratchet)`
|
|
65589
|
-
);
|
|
65590
|
-
this._sendRoomResyncIfCooled(convId, "room_message_skip");
|
|
65591
|
-
return;
|
|
65592
|
-
}
|
|
65593
|
-
} catch (reinitErr) {
|
|
65594
|
-
console.error(
|
|
65595
|
-
`[SecureChannel] Room ratchet re-init failed for conv ${convId.slice(0, 8)}...:`,
|
|
65596
|
-
reinitErr
|
|
65597
|
-
);
|
|
65598
|
-
this._sendRoomResyncIfCooled(convId, "room_reinit_failed");
|
|
65599
|
-
return;
|
|
65600
|
-
}
|
|
65601
|
-
}
|
|
65602
|
-
let messageText;
|
|
65603
|
-
let messageType;
|
|
65604
|
-
try {
|
|
65605
|
-
const parsed = JSON.parse(plaintext);
|
|
65606
|
-
messageType = parsed.type || "message";
|
|
65607
|
-
messageText = parsed.text || plaintext;
|
|
65608
|
-
} catch {
|
|
65609
|
-
messageType = "message";
|
|
65610
|
-
messageText = plaintext;
|
|
65611
|
-
}
|
|
65612
|
-
if (CREDENTIAL_MESSAGE_TYPES.has(messageType)) {
|
|
65613
|
-
this._handleCredentialMessage(msgData.room_id, messageType, messageText, msgData.message_id);
|
|
65614
|
-
if (msgData.created_at && this._persisted) {
|
|
65615
|
-
this._persisted.lastMessageTimestamp = msgData.created_at;
|
|
65616
|
-
}
|
|
65617
|
-
await this._persistState();
|
|
65618
|
-
return;
|
|
65619
|
-
}
|
|
65620
|
-
if (!ROOM_AGENT_TYPES.has(messageType)) {
|
|
65621
|
-
return;
|
|
65622
|
-
}
|
|
65623
|
-
if (!session.activated) {
|
|
65624
|
-
session.activated = true;
|
|
65625
|
-
console.log(
|
|
65626
|
-
`[SecureChannel] Room session ${convId.slice(0, 8)}... activated by first message`
|
|
65627
|
-
);
|
|
65628
|
-
}
|
|
65629
|
-
if (msgData.message_id) {
|
|
65630
|
-
this._sendAck(msgData.message_id);
|
|
65631
|
-
}
|
|
65632
|
-
if (msgData.created_at && this._persisted) {
|
|
65633
|
-
this._persisted.lastMessageTimestamp = msgData.created_at;
|
|
65634
|
-
}
|
|
65635
|
-
await this._persistState();
|
|
65636
|
-
const legacyRoomMembers = this._persisted?.rooms?.[msgData.room_id]?.members ?? [];
|
|
65637
|
-
const legacySenderMember = legacyRoomMembers.find((m2) => m2.deviceId === msgData.sender_device_id);
|
|
65638
|
-
const legacySenderIsAgent = legacySenderMember?.entityType === "agent";
|
|
65639
|
-
const legacySenderLabel = legacySenderMember?.displayName || "someone";
|
|
65640
|
-
const metadata = {
|
|
65641
|
-
messageId: msgData.message_id ?? "",
|
|
65642
|
-
conversationId: convId,
|
|
65643
|
-
timestamp: msgData.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
65644
|
-
messageType,
|
|
65645
|
-
roomId: msgData.room_id,
|
|
65646
|
-
senderDeviceId: msgData.sender_device_id,
|
|
65647
|
-
senderIsAgent: legacySenderIsAgent,
|
|
65648
|
-
senderName: legacySenderLabel,
|
|
65649
|
-
roomName: this._persisted?.rooms?.[msgData.room_id]?.name
|
|
65650
|
-
};
|
|
65651
|
-
this._appendHistory("owner", messageText, `room:${msgData.room_id}`);
|
|
65652
|
-
this.emit("room_message", {
|
|
65653
|
-
roomId: msgData.room_id,
|
|
65654
|
-
senderDeviceId: msgData.sender_device_id,
|
|
65655
|
-
senderName: legacySenderLabel,
|
|
65656
|
-
plaintext: messageText,
|
|
65657
|
-
messageType,
|
|
65658
|
-
timestamp: msgData.created_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
65659
|
-
});
|
|
65660
|
-
const legacyContextualMessage = legacySenderIsAgent ? messageText : `[${legacySenderLabel}]: ${messageText}`;
|
|
65661
|
-
Promise.resolve(this.config.onMessage?.(legacyContextualMessage, metadata)).catch((err) => {
|
|
65662
|
-
console.error("[SecureChannel] onMessage callback error:", err);
|
|
65663
|
-
});
|
|
65664
|
-
}
|
|
66411
|
+
// _sendRoomResyncIfCooled removed — rooms are MLS-only now
|
|
66412
|
+
// _handleRoomMessage removed — rooms are MLS-only now
|
|
65665
66413
|
/**
|
|
65666
66414
|
* Handle credential protocol messages (grant, revoke, request).
|
|
65667
66415
|
* These are intercepted before reaching the agent's onMessage callback.
|
|
@@ -65750,20 +66498,7 @@ ${messageText}`;
|
|
|
65750
66498
|
purgeRoomCredentials(roomId) {
|
|
65751
66499
|
this._credentialStore.purgeForRoom(roomId);
|
|
65752
66500
|
}
|
|
65753
|
-
|
|
65754
|
-
* Find the pairwise conversation ID for a given sender in a room.
|
|
65755
|
-
*/
|
|
65756
|
-
_findConversationForSender(senderDeviceId, roomId) {
|
|
65757
|
-
const room = this._persisted?.rooms?.[roomId];
|
|
65758
|
-
if (!room) return null;
|
|
65759
|
-
for (const convId of room.conversationIds) {
|
|
65760
|
-
const session = this._sessions.get(convId);
|
|
65761
|
-
if (session && session.ownerDeviceId === senderDeviceId) {
|
|
65762
|
-
return convId;
|
|
65763
|
-
}
|
|
65764
|
-
}
|
|
65765
|
-
return null;
|
|
65766
|
-
}
|
|
66501
|
+
// _findConversationForSender removed — rooms are MLS-only now
|
|
65767
66502
|
// ---------------------------------------------------------------------------
|
|
65768
66503
|
// MLS room message handlers
|
|
65769
66504
|
// ---------------------------------------------------------------------------
|
|
@@ -65787,11 +66522,33 @@ ${messageText}`;
|
|
|
65787
66522
|
return;
|
|
65788
66523
|
}
|
|
65789
66524
|
}
|
|
65790
|
-
|
|
65791
|
-
|
|
65792
|
-
|
|
66525
|
+
const resolvedRoomId = roomId;
|
|
66526
|
+
this._lastInboundRoomId = resolvedRoomId;
|
|
66527
|
+
const mlsGroup = this._mlsGroups.get(resolvedRoomId);
|
|
66528
|
+
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(",")}]`);
|
|
65793
66529
|
if (!mlsGroup?.isInitialized) {
|
|
65794
|
-
console.warn(`[SecureChannel] MLS group not loaded for room ${
|
|
66530
|
+
console.warn(`[SecureChannel] MLS group not loaded for room ${resolvedRoomId.slice(0, 8)}, requesting Welcome`);
|
|
66531
|
+
try {
|
|
66532
|
+
const { MLSGroupManager: MLS } = await init_dist().then(() => dist_exports);
|
|
66533
|
+
const mgr = new MLS();
|
|
66534
|
+
const kp = await mgr.generateKeyPackage(new TextEncoder().encode(this._deviceId));
|
|
66535
|
+
const kpBytes = MLS.serializeKeyPackage(kp.publicPackage);
|
|
66536
|
+
const kpHex = Buffer.from(kpBytes).toString("hex");
|
|
66537
|
+
await fetch(`${this.config.apiUrl}/api/v1/mls/key-packages`, {
|
|
66538
|
+
method: "POST",
|
|
66539
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66540
|
+
body: JSON.stringify({ key_package: kpHex, device_id: this._deviceId })
|
|
66541
|
+
});
|
|
66542
|
+
this._pendingMlsKpBundle = kp;
|
|
66543
|
+
await fetch(`${this.config.apiUrl}/api/v1/mls/groups/${groupId}/request-welcome`, {
|
|
66544
|
+
method: "POST",
|
|
66545
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66546
|
+
body: JSON.stringify({ device_id: this._deviceId })
|
|
66547
|
+
});
|
|
66548
|
+
console.log(`[SecureChannel] Welcome requested for room ${resolvedRoomId.slice(0, 8)} group ${groupId?.slice(0, 8)}`);
|
|
66549
|
+
} catch (reqErr) {
|
|
66550
|
+
console.warn(`[SecureChannel] Welcome request failed for room ${resolvedRoomId.slice(0, 8)}:`, reqErr);
|
|
66551
|
+
}
|
|
65795
66552
|
return;
|
|
65796
66553
|
}
|
|
65797
66554
|
try {
|
|
@@ -65813,7 +66570,7 @@ ${messageText}`;
|
|
|
65813
66570
|
messageText = rawPlaintext;
|
|
65814
66571
|
}
|
|
65815
66572
|
if (CREDENTIAL_MESSAGE_TYPES.has(messageType)) {
|
|
65816
|
-
this._handleCredentialMessage(
|
|
66573
|
+
this._handleCredentialMessage(resolvedRoomId, messageType, messageText, data.message_id);
|
|
65817
66574
|
if (data.created_at && this._persisted) {
|
|
65818
66575
|
this._persisted.lastMessageTimestamp = data.created_at;
|
|
65819
66576
|
}
|
|
@@ -65828,13 +66585,13 @@ ${messageText}`;
|
|
|
65828
66585
|
}
|
|
65829
66586
|
if (data.created_at && this._persisted) {
|
|
65830
66587
|
this._persisted.lastMessageTimestamp = data.created_at;
|
|
65831
|
-
const roomState = this._persisted.rooms?.[
|
|
66588
|
+
const roomState = this._persisted.rooms?.[resolvedRoomId];
|
|
65832
66589
|
if (roomState) {
|
|
65833
66590
|
roomState.lastMlsMessageTs = data.created_at;
|
|
65834
66591
|
}
|
|
65835
66592
|
}
|
|
65836
66593
|
await this._persistState();
|
|
65837
|
-
const roomMembers = this._persisted?.rooms?.[
|
|
66594
|
+
const roomMembers = this._persisted?.rooms?.[resolvedRoomId]?.members ?? [];
|
|
65838
66595
|
const senderMember = roomMembers.find((m2) => m2.deviceId === senderDeviceId);
|
|
65839
66596
|
const senderIsAgent = senderMember?.entityType === "agent";
|
|
65840
66597
|
const metadata = {
|
|
@@ -65842,16 +66599,16 @@ ${messageText}`;
|
|
|
65842
66599
|
conversationId: "",
|
|
65843
66600
|
timestamp: data.created_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
65844
66601
|
messageType,
|
|
65845
|
-
roomId,
|
|
66602
|
+
roomId: resolvedRoomId,
|
|
65846
66603
|
senderDeviceId,
|
|
65847
66604
|
senderIsAgent,
|
|
65848
66605
|
senderName: senderMember?.displayName || "unknown",
|
|
65849
|
-
roomName: this._persisted?.rooms?.[
|
|
66606
|
+
roomName: this._persisted?.rooms?.[resolvedRoomId]?.name
|
|
65850
66607
|
};
|
|
65851
66608
|
const senderLabel = senderMember?.displayName || "someone";
|
|
65852
|
-
this._appendHistory("owner", messageText, `room:${
|
|
66609
|
+
this._appendHistory("owner", messageText, `room:${resolvedRoomId}`);
|
|
65853
66610
|
this.emit("room_message", {
|
|
65854
|
-
roomId,
|
|
66611
|
+
roomId: resolvedRoomId,
|
|
65855
66612
|
senderDeviceId,
|
|
65856
66613
|
senderName: senderLabel,
|
|
65857
66614
|
plaintext: messageText,
|
|
@@ -65863,7 +66620,7 @@ ${messageText}`;
|
|
|
65863
66620
|
console.error("[SecureChannel] onMessage callback error (MLS):", err);
|
|
65864
66621
|
});
|
|
65865
66622
|
} catch (err) {
|
|
65866
|
-
console.error(`[SecureChannel] MLS room decrypt failed for ${
|
|
66623
|
+
console.error(`[SecureChannel] MLS room decrypt failed for ${resolvedRoomId.slice(0, 8)}:`, err);
|
|
65867
66624
|
}
|
|
65868
66625
|
}
|
|
65869
66626
|
async _handleMlsCommit(data) {
|
|
@@ -65892,7 +66649,7 @@ ${messageText}`;
|
|
|
65892
66649
|
try {
|
|
65893
66650
|
const welcomeBytes = new Uint8Array(Buffer.from(data.payload, "hex"));
|
|
65894
66651
|
const mgr = new MLSGroupManager();
|
|
65895
|
-
const kp = this._mlsKeyPackage ?? await (async () => {
|
|
66652
|
+
const kp = this._pendingMlsKpBundle ?? this._mlsKeyPackage ?? await (async () => {
|
|
65896
66653
|
const identity = new TextEncoder().encode(this._deviceId);
|
|
65897
66654
|
return mgr.generateKeyPackage(identity);
|
|
65898
66655
|
})();
|
|
@@ -65909,11 +66666,15 @@ ${messageText}`;
|
|
|
65909
66666
|
console.log(`[SecureChannel] Joined 1:1 MLS group for conv ${conversationId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
|
|
65910
66667
|
return;
|
|
65911
66668
|
}
|
|
66669
|
+
const welcomeRoomId = data.room_id;
|
|
65912
66670
|
for (const [roomId, room] of Object.entries(this._persisted?.rooms ?? {})) {
|
|
65913
|
-
if (room.mlsGroupId === groupId) {
|
|
66671
|
+
if (room.mlsGroupId === groupId || roomId === welcomeRoomId) {
|
|
66672
|
+
room.mlsGroupId = groupId;
|
|
65914
66673
|
this._mlsGroups.set(roomId, mgr);
|
|
65915
66674
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
|
|
66675
|
+
await this._persistState();
|
|
65916
66676
|
console.log(`[SecureChannel] Joined MLS group for room ${roomId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
|
|
66677
|
+
this._pendingMlsKpBundle = void 0;
|
|
65917
66678
|
return;
|
|
65918
66679
|
}
|
|
65919
66680
|
}
|
|
@@ -66190,22 +66951,6 @@ ${messageText}`;
|
|
|
66190
66951
|
}
|
|
66191
66952
|
}
|
|
66192
66953
|
if (roomId) {
|
|
66193
|
-
try {
|
|
66194
|
-
await this._handleRoomMessage({
|
|
66195
|
-
room_id: roomId,
|
|
66196
|
-
sender_device_id: msg.sender_device_id,
|
|
66197
|
-
conversation_id: msg.conversation_id,
|
|
66198
|
-
header_blob: msg.header_blob,
|
|
66199
|
-
ciphertext: msg.ciphertext,
|
|
66200
|
-
message_id: msg.id,
|
|
66201
|
-
created_at: msg.created_at
|
|
66202
|
-
});
|
|
66203
|
-
} catch (roomErr) {
|
|
66204
|
-
console.warn(
|
|
66205
|
-
`[SecureChannel] Sync room message failed for ${msg.conversation_id.slice(0, 8)}...:`,
|
|
66206
|
-
roomErr
|
|
66207
|
-
);
|
|
66208
|
-
}
|
|
66209
66954
|
this._persisted.lastMessageTimestamp = msg.created_at;
|
|
66210
66955
|
since = msg.created_at;
|
|
66211
66956
|
continue;
|