@agentvault/agentvault 0.19.59 → 0.19.61
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/channel.d.ts +7 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/cli.js +1301 -59
- package/dist/cli.js.map +3 -3
- package/dist/index.js +1239 -59
- package/dist/index.js.map +3 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44659,6 +44659,13 @@ function computeFingerprint(publicKey) {
|
|
|
44659
44659
|
function createProofOfPossession(privateKey, publicKey) {
|
|
44660
44660
|
return libsodium_wrappers_default.crypto_sign_detached(publicKey, privateKey);
|
|
44661
44661
|
}
|
|
44662
|
+
function verifyProofOfPossession(proof, publicKey) {
|
|
44663
|
+
try {
|
|
44664
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(proof, publicKey, publicKey);
|
|
44665
|
+
} catch {
|
|
44666
|
+
return false;
|
|
44667
|
+
}
|
|
44668
|
+
}
|
|
44662
44669
|
var init_keys = __esm({
|
|
44663
44670
|
async "../crypto/dist/keys.js"() {
|
|
44664
44671
|
"use strict";
|
|
@@ -45127,6 +45134,74 @@ function jsonCanonical(value) {
|
|
|
45127
45134
|
}
|
|
45128
45135
|
return JSON.stringify(value);
|
|
45129
45136
|
}
|
|
45137
|
+
function base58Encode(bytes) {
|
|
45138
|
+
let zeros = 0;
|
|
45139
|
+
for (const b2 of bytes) {
|
|
45140
|
+
if (b2 === 0)
|
|
45141
|
+
zeros++;
|
|
45142
|
+
else
|
|
45143
|
+
break;
|
|
45144
|
+
}
|
|
45145
|
+
let num = BigInt(0);
|
|
45146
|
+
for (const b2 of bytes) {
|
|
45147
|
+
num = num * 256n + BigInt(b2);
|
|
45148
|
+
}
|
|
45149
|
+
let result = "";
|
|
45150
|
+
while (num > 0n) {
|
|
45151
|
+
const remainder = Number(num % 58n);
|
|
45152
|
+
num = num / 58n;
|
|
45153
|
+
result = BASE58_ALPHABET[remainder] + result;
|
|
45154
|
+
}
|
|
45155
|
+
return "1".repeat(zeros) + result;
|
|
45156
|
+
}
|
|
45157
|
+
function base58Decode(str) {
|
|
45158
|
+
let zeros = 0;
|
|
45159
|
+
for (const c2 of str) {
|
|
45160
|
+
if (c2 === "1")
|
|
45161
|
+
zeros++;
|
|
45162
|
+
else
|
|
45163
|
+
break;
|
|
45164
|
+
}
|
|
45165
|
+
let num = BigInt(0);
|
|
45166
|
+
for (const c2 of str.slice(zeros)) {
|
|
45167
|
+
const idx = BASE58_ALPHABET.indexOf(c2);
|
|
45168
|
+
if (idx === -1)
|
|
45169
|
+
throw new Error(`Invalid base58 character: ${c2}`);
|
|
45170
|
+
num = num * 58n + BigInt(idx);
|
|
45171
|
+
}
|
|
45172
|
+
const hex3 = num === 0n ? "" : num.toString(16).padStart(2, "0");
|
|
45173
|
+
const paddedHex = hex3.length % 2 ? "0" + hex3 : hex3;
|
|
45174
|
+
const dataBytes = new Uint8Array((paddedHex.match(/.{2}/g) ?? []).map((b2) => parseInt(b2, 16)));
|
|
45175
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
45176
|
+
result.set(dataBytes, zeros);
|
|
45177
|
+
return result;
|
|
45178
|
+
}
|
|
45179
|
+
function publicKeyToMultibase(publicKey) {
|
|
45180
|
+
const prefixed = new Uint8Array(2 + publicKey.length);
|
|
45181
|
+
prefixed[0] = 237;
|
|
45182
|
+
prefixed[1] = 1;
|
|
45183
|
+
prefixed.set(publicKey, 2);
|
|
45184
|
+
return "z" + base58Encode(prefixed);
|
|
45185
|
+
}
|
|
45186
|
+
function multibaseToPublicKey(multibase) {
|
|
45187
|
+
if (!multibase.startsWith("z")) {
|
|
45188
|
+
throw new Error("Multibase string must start with 'z' (base58btc)");
|
|
45189
|
+
}
|
|
45190
|
+
const decoded = base58Decode(multibase.slice(1));
|
|
45191
|
+
if (decoded.length < 2 || decoded[0] !== 237 || decoded[1] !== 1) {
|
|
45192
|
+
throw new Error("Invalid Ed25519 multicodec prefix");
|
|
45193
|
+
}
|
|
45194
|
+
return decoded.slice(2);
|
|
45195
|
+
}
|
|
45196
|
+
async function signDocument(document, privateKey) {
|
|
45197
|
+
await libsodium_wrappers_default.ready;
|
|
45198
|
+
const canonical = canonicalize(document);
|
|
45199
|
+
const domainPrefix = libsodium_wrappers_default.from_string(DOMAIN_DID_DOCUMENT);
|
|
45200
|
+
const message = new Uint8Array(domainPrefix.length + canonical.length);
|
|
45201
|
+
message.set(domainPrefix);
|
|
45202
|
+
message.set(canonical, domainPrefix.length);
|
|
45203
|
+
return libsodium_wrappers_default.crypto_sign_detached(message, privateKey);
|
|
45204
|
+
}
|
|
45130
45205
|
async function verifyDocumentSignature(document, signature, publicKey) {
|
|
45131
45206
|
await libsodium_wrappers_default.ready;
|
|
45132
45207
|
const canonical = canonicalize(document);
|
|
@@ -45140,12 +45215,61 @@ async function verifyDocumentSignature(document, signature, publicKey) {
|
|
|
45140
45215
|
return false;
|
|
45141
45216
|
}
|
|
45142
45217
|
}
|
|
45143
|
-
|
|
45218
|
+
function buildDidDocument(params) {
|
|
45219
|
+
const { hubAddress, ownerPublicKey, agentPublicKey, serviceEndpoint, profileEndpoint } = params;
|
|
45220
|
+
const didId = `did:hub:${hubAddress}`;
|
|
45221
|
+
const ownerMultibase = publicKeyToMultibase(ownerPublicKey);
|
|
45222
|
+
const agentMultibase = publicKeyToMultibase(agentPublicKey);
|
|
45223
|
+
const controllerDid = `did:key:${ownerMultibase}`;
|
|
45224
|
+
const now = params.created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45225
|
+
return {
|
|
45226
|
+
"@context": [
|
|
45227
|
+
"https://www.w3.org/ns/did/v1",
|
|
45228
|
+
"https://w3id.org/security/suites/ed25519-2020/v1"
|
|
45229
|
+
],
|
|
45230
|
+
id: didId,
|
|
45231
|
+
controller: controllerDid,
|
|
45232
|
+
verificationMethod: [
|
|
45233
|
+
{
|
|
45234
|
+
id: `${didId}#owner-key`,
|
|
45235
|
+
type: "Ed25519VerificationKey2020",
|
|
45236
|
+
controller: didId,
|
|
45237
|
+
publicKeyMultibase: ownerMultibase
|
|
45238
|
+
},
|
|
45239
|
+
{
|
|
45240
|
+
id: `${didId}#agent-key`,
|
|
45241
|
+
type: "Ed25519VerificationKey2020",
|
|
45242
|
+
controller: didId,
|
|
45243
|
+
publicKeyMultibase: agentMultibase
|
|
45244
|
+
}
|
|
45245
|
+
],
|
|
45246
|
+
authentication: [`${didId}#owner-key`],
|
|
45247
|
+
assertionMethod: [`${didId}#owner-key`, `${didId}#agent-key`],
|
|
45248
|
+
service: [
|
|
45249
|
+
{
|
|
45250
|
+
id: `${didId}#messaging`,
|
|
45251
|
+
type: "AgentVaultSecureChannel",
|
|
45252
|
+
serviceEndpoint
|
|
45253
|
+
},
|
|
45254
|
+
{
|
|
45255
|
+
id: `${didId}#profile`,
|
|
45256
|
+
type: "AgentVaultProfile",
|
|
45257
|
+
serviceEndpoint: profileEndpoint
|
|
45258
|
+
}
|
|
45259
|
+
],
|
|
45260
|
+
created: now,
|
|
45261
|
+
updated: now
|
|
45262
|
+
};
|
|
45263
|
+
}
|
|
45264
|
+
var DOMAIN_DID_DOCUMENT, DOMAIN_TRANSFER_INTENT, DOMAIN_TRANSFER_ACCEPT, BASE58_ALPHABET;
|
|
45144
45265
|
var init_did = __esm({
|
|
45145
45266
|
async "../crypto/dist/did.js"() {
|
|
45146
45267
|
"use strict";
|
|
45147
45268
|
await init_libsodium_wrappers();
|
|
45148
45269
|
DOMAIN_DID_DOCUMENT = "DID-DOCUMENT:";
|
|
45270
|
+
DOMAIN_TRANSFER_INTENT = "TRANSFER-INTENT:";
|
|
45271
|
+
DOMAIN_TRANSFER_ACCEPT = "TRANSFER-ACCEPT:";
|
|
45272
|
+
BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
45149
45273
|
}
|
|
45150
45274
|
});
|
|
45151
45275
|
|
|
@@ -45428,25 +45552,373 @@ var init_scan_engine = __esm({
|
|
|
45428
45552
|
});
|
|
45429
45553
|
|
|
45430
45554
|
// ../crypto/dist/merkle.js
|
|
45555
|
+
function jcsCanonical(value) {
|
|
45556
|
+
if (value === void 0)
|
|
45557
|
+
return void 0;
|
|
45558
|
+
if (value === null)
|
|
45559
|
+
return "null";
|
|
45560
|
+
if (typeof value === "boolean" || typeof value === "number")
|
|
45561
|
+
return JSON.stringify(value);
|
|
45562
|
+
if (typeof value === "string")
|
|
45563
|
+
return JSON.stringify(value);
|
|
45564
|
+
if (Array.isArray(value)) {
|
|
45565
|
+
return "[" + value.map(jcsCanonical).join(",") + "]";
|
|
45566
|
+
}
|
|
45567
|
+
if (typeof value === "object") {
|
|
45568
|
+
const keys = Object.keys(value).sort();
|
|
45569
|
+
const entries = keys.map((k2) => {
|
|
45570
|
+
const v2 = jcsCanonical(value[k2]);
|
|
45571
|
+
if (v2 === void 0)
|
|
45572
|
+
return void 0;
|
|
45573
|
+
return JSON.stringify(k2) + ":" + v2;
|
|
45574
|
+
}).filter((entry) => entry !== void 0);
|
|
45575
|
+
return "{" + entries.join(",") + "}";
|
|
45576
|
+
}
|
|
45577
|
+
return JSON.stringify(value);
|
|
45578
|
+
}
|
|
45579
|
+
function hexToBytes(hex3) {
|
|
45580
|
+
const h2 = hex3.startsWith("0x") ? hex3.slice(2) : hex3;
|
|
45581
|
+
const bytes = new Uint8Array(h2.length / 2);
|
|
45582
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
45583
|
+
bytes[i2] = parseInt(h2.substr(i2 * 2, 2), 16);
|
|
45584
|
+
}
|
|
45585
|
+
return bytes;
|
|
45586
|
+
}
|
|
45587
|
+
function bytesToHex(bytes) {
|
|
45588
|
+
return Array.from(bytes).map((b2) => b2.toString(16).padStart(2, "0")).join("");
|
|
45589
|
+
}
|
|
45590
|
+
function computeDidHash(didDocument) {
|
|
45591
|
+
const json2 = jcsCanonical(didDocument) ?? "";
|
|
45592
|
+
const bytes = libsodium_wrappers_default.from_string(json2);
|
|
45593
|
+
const hash2 = libsodium_wrappers_default.crypto_hash_sha256(bytes);
|
|
45594
|
+
return "0x" + bytesToHex(hash2);
|
|
45595
|
+
}
|
|
45596
|
+
function verifyMerkleProof(leafHash, proof, merkleRoot) {
|
|
45597
|
+
let current = hexToBytes(leafHash);
|
|
45598
|
+
for (const step of proof) {
|
|
45599
|
+
const sibling2 = hexToBytes(step.hash);
|
|
45600
|
+
const combined = new Uint8Array(current.length + sibling2.length);
|
|
45601
|
+
if (step.position === "left") {
|
|
45602
|
+
combined.set(sibling2);
|
|
45603
|
+
combined.set(current, sibling2.length);
|
|
45604
|
+
} else {
|
|
45605
|
+
combined.set(current);
|
|
45606
|
+
combined.set(sibling2, current.length);
|
|
45607
|
+
}
|
|
45608
|
+
current = libsodium_wrappers_default.crypto_hash_sha256(combined);
|
|
45609
|
+
}
|
|
45610
|
+
const rootBytes = hexToBytes(merkleRoot);
|
|
45611
|
+
if (current.length !== rootBytes.length)
|
|
45612
|
+
return false;
|
|
45613
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
45614
|
+
if (current[i2] !== rootBytes[i2])
|
|
45615
|
+
return false;
|
|
45616
|
+
}
|
|
45617
|
+
return true;
|
|
45618
|
+
}
|
|
45431
45619
|
var init_merkle = __esm({
|
|
45432
45620
|
async "../crypto/dist/merkle.js"() {
|
|
45433
45621
|
"use strict";
|
|
45622
|
+
await init_libsodium_wrappers();
|
|
45434
45623
|
}
|
|
45435
45624
|
});
|
|
45436
45625
|
|
|
45437
45626
|
// ../crypto/dist/vc.js
|
|
45627
|
+
async function sha256(data) {
|
|
45628
|
+
await libsodium_wrappers_default.ready;
|
|
45629
|
+
return libsodium_wrappers_default.crypto_hash_sha256(data);
|
|
45630
|
+
}
|
|
45631
|
+
function base58Encode2(bytes) {
|
|
45632
|
+
let zeros = 0;
|
|
45633
|
+
for (const b2 of bytes) {
|
|
45634
|
+
if (b2 === 0)
|
|
45635
|
+
zeros++;
|
|
45636
|
+
else
|
|
45637
|
+
break;
|
|
45638
|
+
}
|
|
45639
|
+
let num = BigInt(0);
|
|
45640
|
+
for (const b2 of bytes) {
|
|
45641
|
+
num = num * 256n + BigInt(b2);
|
|
45642
|
+
}
|
|
45643
|
+
let result = "";
|
|
45644
|
+
while (num > 0n) {
|
|
45645
|
+
const remainder = Number(num % 58n);
|
|
45646
|
+
num = num / 58n;
|
|
45647
|
+
result = BASE58_ALPHABET2[remainder] + result;
|
|
45648
|
+
}
|
|
45649
|
+
return "1".repeat(zeros) + result;
|
|
45650
|
+
}
|
|
45651
|
+
function base58Decode2(str) {
|
|
45652
|
+
let zeros = 0;
|
|
45653
|
+
for (const c2 of str) {
|
|
45654
|
+
if (c2 === "1")
|
|
45655
|
+
zeros++;
|
|
45656
|
+
else
|
|
45657
|
+
break;
|
|
45658
|
+
}
|
|
45659
|
+
let num = BigInt(0);
|
|
45660
|
+
for (const c2 of str.slice(zeros)) {
|
|
45661
|
+
const idx = BASE58_ALPHABET2.indexOf(c2);
|
|
45662
|
+
if (idx === -1)
|
|
45663
|
+
throw new Error(`Invalid base58 character: ${c2}`);
|
|
45664
|
+
num = num * 58n + BigInt(idx);
|
|
45665
|
+
}
|
|
45666
|
+
const hex3 = num === 0n ? "" : num.toString(16).padStart(2, "0");
|
|
45667
|
+
const paddedHex = hex3.length % 2 ? "0" + hex3 : hex3;
|
|
45668
|
+
const dataBytes = new Uint8Array((paddedHex.match(/.{2}/g) ?? []).map((b2) => parseInt(b2, 16)));
|
|
45669
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
45670
|
+
result.set(dataBytes, zeros);
|
|
45671
|
+
return result;
|
|
45672
|
+
}
|
|
45673
|
+
async function computeHashData(document, proofConfig) {
|
|
45674
|
+
const proofConfigBytes = canonicalize(proofConfig);
|
|
45675
|
+
const proofConfigHash = await sha256(proofConfigBytes);
|
|
45676
|
+
const docWithoutProof = { ...document };
|
|
45677
|
+
delete docWithoutProof.proof;
|
|
45678
|
+
const documentBytes = canonicalize(docWithoutProof);
|
|
45679
|
+
const documentHash = await sha256(documentBytes);
|
|
45680
|
+
const hashData = new Uint8Array(64);
|
|
45681
|
+
hashData.set(proofConfigHash, 0);
|
|
45682
|
+
hashData.set(documentHash, 32);
|
|
45683
|
+
return hashData;
|
|
45684
|
+
}
|
|
45685
|
+
async function signWithDataIntegrity(document, privateKey, verificationMethod, proofPurpose = "assertionMethod", created) {
|
|
45686
|
+
await libsodium_wrappers_default.ready;
|
|
45687
|
+
const timestamp = created ?? (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45688
|
+
const proofConfig = {
|
|
45689
|
+
type: "DataIntegrityProof",
|
|
45690
|
+
cryptosuite: CRYPTOSUITE,
|
|
45691
|
+
created: timestamp,
|
|
45692
|
+
verificationMethod,
|
|
45693
|
+
proofPurpose
|
|
45694
|
+
};
|
|
45695
|
+
const hashData = await computeHashData(document, proofConfig);
|
|
45696
|
+
const signature = libsodium_wrappers_default.crypto_sign_detached(hashData, privateKey);
|
|
45697
|
+
const proofValue = "z" + base58Encode2(signature);
|
|
45698
|
+
const proof = {
|
|
45699
|
+
type: "DataIntegrityProof",
|
|
45700
|
+
cryptosuite: CRYPTOSUITE,
|
|
45701
|
+
created: timestamp,
|
|
45702
|
+
verificationMethod,
|
|
45703
|
+
proofPurpose,
|
|
45704
|
+
proofValue
|
|
45705
|
+
};
|
|
45706
|
+
return { ...document, proof };
|
|
45707
|
+
}
|
|
45708
|
+
async function verifyDataIntegrity(document, publicKey) {
|
|
45709
|
+
await libsodium_wrappers_default.ready;
|
|
45710
|
+
const proof = document.proof;
|
|
45711
|
+
if (!proof || proof.type !== "DataIntegrityProof" || proof.cryptosuite !== CRYPTOSUITE) {
|
|
45712
|
+
return false;
|
|
45713
|
+
}
|
|
45714
|
+
if (!proof.proofValue.startsWith("z")) {
|
|
45715
|
+
return false;
|
|
45716
|
+
}
|
|
45717
|
+
const signature = base58Decode2(proof.proofValue.slice(1));
|
|
45718
|
+
if (signature.length !== 64) {
|
|
45719
|
+
return false;
|
|
45720
|
+
}
|
|
45721
|
+
const proofConfig = {
|
|
45722
|
+
type: proof.type,
|
|
45723
|
+
cryptosuite: proof.cryptosuite,
|
|
45724
|
+
created: proof.created,
|
|
45725
|
+
verificationMethod: proof.verificationMethod,
|
|
45726
|
+
proofPurpose: proof.proofPurpose
|
|
45727
|
+
};
|
|
45728
|
+
const hashData = await computeHashData(document, proofConfig);
|
|
45729
|
+
try {
|
|
45730
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(signature, hashData, publicKey);
|
|
45731
|
+
} catch {
|
|
45732
|
+
return false;
|
|
45733
|
+
}
|
|
45734
|
+
}
|
|
45735
|
+
function buildAgentTrustCredential(params) {
|
|
45736
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45737
|
+
return {
|
|
45738
|
+
"@context": [
|
|
45739
|
+
VC_CONTEXT_V2,
|
|
45740
|
+
{
|
|
45741
|
+
AgentTrustCredential: "https://agentvault.chat/vocab#AgentTrustCredential",
|
|
45742
|
+
trustTier: "https://agentvault.chat/vocab#trustTier",
|
|
45743
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore",
|
|
45744
|
+
scoreWindow: "https://agentvault.chat/vocab#scoreWindow",
|
|
45745
|
+
scoreDimensions: "https://agentvault.chat/vocab#scoreDimensions",
|
|
45746
|
+
volume: "https://agentvault.chat/vocab#volume",
|
|
45747
|
+
responsiveness: "https://agentvault.chat/vocab#responsiveness",
|
|
45748
|
+
uptime: "https://agentvault.chat/vocab#uptime",
|
|
45749
|
+
compliance: "https://agentvault.chat/vocab#compliance",
|
|
45750
|
+
verificationEndpoint: "https://agentvault.chat/vocab#verificationEndpoint"
|
|
45751
|
+
}
|
|
45752
|
+
],
|
|
45753
|
+
id: params.credentialId,
|
|
45754
|
+
type: ["VerifiableCredential", "AgentTrustCredential"],
|
|
45755
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45756
|
+
validFrom: params.validFrom ?? now,
|
|
45757
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45758
|
+
credentialSubject: {
|
|
45759
|
+
id: params.subjectDid,
|
|
45760
|
+
trustTier: params.trustTier,
|
|
45761
|
+
compositeScore: params.compositeScore,
|
|
45762
|
+
scoreWindow: params.scoreWindow,
|
|
45763
|
+
...params.dimensions ? {
|
|
45764
|
+
scoreDimensions: {
|
|
45765
|
+
volume: params.dimensions.volume,
|
|
45766
|
+
responsiveness: params.dimensions.responsiveness,
|
|
45767
|
+
uptime: params.dimensions.uptime,
|
|
45768
|
+
compliance: params.dimensions.compliance
|
|
45769
|
+
}
|
|
45770
|
+
} : {},
|
|
45771
|
+
...params.verificationEndpoint ? { verificationEndpoint: params.verificationEndpoint } : {}
|
|
45772
|
+
}
|
|
45773
|
+
};
|
|
45774
|
+
}
|
|
45775
|
+
function buildSkillAttestation(params) {
|
|
45776
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45777
|
+
return {
|
|
45778
|
+
"@context": [
|
|
45779
|
+
VC_CONTEXT_V2,
|
|
45780
|
+
{
|
|
45781
|
+
SkillAttestation: "https://agentvault.chat/vocab#SkillAttestation",
|
|
45782
|
+
skillName: "https://agentvault.chat/vocab#skillName",
|
|
45783
|
+
skillNamespace: "https://agentvault.chat/vocab#skillNamespace",
|
|
45784
|
+
proficiencyLevel: "https://agentvault.chat/vocab#proficiencyLevel",
|
|
45785
|
+
totalInvocations: "https://agentvault.chat/vocab#totalInvocations",
|
|
45786
|
+
successRate: "https://agentvault.chat/vocab#successRate",
|
|
45787
|
+
assessedAt: "https://agentvault.chat/vocab#assessedAt"
|
|
45788
|
+
}
|
|
45789
|
+
],
|
|
45790
|
+
id: params.credentialId,
|
|
45791
|
+
type: ["VerifiableCredential", "SkillAttestation"],
|
|
45792
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45793
|
+
validFrom: params.validFrom ?? now,
|
|
45794
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45795
|
+
credentialSubject: {
|
|
45796
|
+
id: params.subjectDid,
|
|
45797
|
+
skillName: params.skillName,
|
|
45798
|
+
skillNamespace: params.skillNamespace,
|
|
45799
|
+
...params.proficiencyLevel ? { proficiencyLevel: params.proficiencyLevel } : {},
|
|
45800
|
+
...params.totalInvocations !== void 0 ? { totalInvocations: params.totalInvocations } : {},
|
|
45801
|
+
...params.successRate !== void 0 ? { successRate: params.successRate } : {},
|
|
45802
|
+
...params.assessedAt ? { assessedAt: params.assessedAt } : {}
|
|
45803
|
+
}
|
|
45804
|
+
};
|
|
45805
|
+
}
|
|
45806
|
+
function buildPerformanceRecord(params) {
|
|
45807
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45808
|
+
return {
|
|
45809
|
+
"@context": [
|
|
45810
|
+
VC_CONTEXT_V2,
|
|
45811
|
+
{
|
|
45812
|
+
PerformanceRecord: "https://agentvault.chat/vocab#PerformanceRecord",
|
|
45813
|
+
periodStart: "https://agentvault.chat/vocab#periodStart",
|
|
45814
|
+
periodEnd: "https://agentvault.chat/vocab#periodEnd",
|
|
45815
|
+
messagesHandled: "https://agentvault.chat/vocab#messagesHandled",
|
|
45816
|
+
avgResponseTimeMs: "https://agentvault.chat/vocab#avgResponseTimeMs",
|
|
45817
|
+
uptimePercentage: "https://agentvault.chat/vocab#uptimePercentage",
|
|
45818
|
+
policyViolations: "https://agentvault.chat/vocab#policyViolations",
|
|
45819
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore"
|
|
45820
|
+
}
|
|
45821
|
+
],
|
|
45822
|
+
id: params.credentialId,
|
|
45823
|
+
type: ["VerifiableCredential", "PerformanceRecord"],
|
|
45824
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45825
|
+
validFrom: params.validFrom ?? now,
|
|
45826
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45827
|
+
credentialSubject: {
|
|
45828
|
+
id: params.subjectDid,
|
|
45829
|
+
periodStart: params.periodStart,
|
|
45830
|
+
periodEnd: params.periodEnd,
|
|
45831
|
+
messagesHandled: params.messagesHandled,
|
|
45832
|
+
avgResponseTimeMs: params.avgResponseTimeMs,
|
|
45833
|
+
uptimePercentage: params.uptimePercentage,
|
|
45834
|
+
policyViolations: params.policyViolations,
|
|
45835
|
+
compositeScore: params.compositeScore
|
|
45836
|
+
}
|
|
45837
|
+
};
|
|
45838
|
+
}
|
|
45839
|
+
function buildAgentTrustReportCredential(params) {
|
|
45840
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
45841
|
+
const subject = {
|
|
45842
|
+
id: params.subjectDid,
|
|
45843
|
+
reportPeriod: {
|
|
45844
|
+
start: params.reportPeriodStart,
|
|
45845
|
+
end: params.reportPeriodEnd
|
|
45846
|
+
},
|
|
45847
|
+
trustTier: params.trustTier,
|
|
45848
|
+
compositeScore: params.compositeScore
|
|
45849
|
+
};
|
|
45850
|
+
if (params.dimensions)
|
|
45851
|
+
subject.dimensions = params.dimensions;
|
|
45852
|
+
if (params.trending)
|
|
45853
|
+
subject.trending = params.trending;
|
|
45854
|
+
if (params.fleetComparison)
|
|
45855
|
+
subject.fleetComparison = params.fleetComparison;
|
|
45856
|
+
if (params.driftStatus)
|
|
45857
|
+
subject.driftStatus = params.driftStatus;
|
|
45858
|
+
if (params.auditIntegrity)
|
|
45859
|
+
subject.auditIntegrity = params.auditIntegrity;
|
|
45860
|
+
if (params.telemetrySummary)
|
|
45861
|
+
subject.telemetrySummary = params.telemetrySummary;
|
|
45862
|
+
if (params.verificationEndpoint)
|
|
45863
|
+
subject.verificationEndpoint = params.verificationEndpoint;
|
|
45864
|
+
return {
|
|
45865
|
+
"@context": [
|
|
45866
|
+
VC_CONTEXT_V2,
|
|
45867
|
+
{
|
|
45868
|
+
AgentTrustReport: "https://agentvault.chat/vocab#AgentTrustReport",
|
|
45869
|
+
reportPeriod: "https://agentvault.chat/vocab#reportPeriod",
|
|
45870
|
+
trustTier: "https://agentvault.chat/vocab#trustTier",
|
|
45871
|
+
compositeScore: "https://agentvault.chat/vocab#compositeScore",
|
|
45872
|
+
dimensions: "https://agentvault.chat/vocab#dimensions",
|
|
45873
|
+
trending: "https://agentvault.chat/vocab#trending",
|
|
45874
|
+
fleetComparison: "https://agentvault.chat/vocab#fleetComparison",
|
|
45875
|
+
driftStatus: "https://agentvault.chat/vocab#driftStatus",
|
|
45876
|
+
auditIntegrity: "https://agentvault.chat/vocab#auditIntegrity",
|
|
45877
|
+
telemetrySummary: "https://agentvault.chat/vocab#telemetrySummary",
|
|
45878
|
+
verificationEndpoint: "https://agentvault.chat/vocab#verificationEndpoint"
|
|
45879
|
+
}
|
|
45880
|
+
],
|
|
45881
|
+
id: params.credentialId,
|
|
45882
|
+
type: ["VerifiableCredential", "AgentTrustReport"],
|
|
45883
|
+
issuer: params.issuerName ? { id: params.issuerDid, name: params.issuerName } : params.issuerDid,
|
|
45884
|
+
validFrom: params.validFrom ?? now,
|
|
45885
|
+
...params.validUntil ? { validUntil: params.validUntil } : {},
|
|
45886
|
+
credentialSubject: subject
|
|
45887
|
+
};
|
|
45888
|
+
}
|
|
45889
|
+
function buildVerifiablePresentation(holderDid, credentials, presentationId) {
|
|
45890
|
+
return {
|
|
45891
|
+
"@context": [VC_CONTEXT_V2],
|
|
45892
|
+
type: "VerifiablePresentation",
|
|
45893
|
+
...presentationId ? { id: presentationId } : {},
|
|
45894
|
+
holder: holderDid,
|
|
45895
|
+
verifiableCredential: credentials
|
|
45896
|
+
};
|
|
45897
|
+
}
|
|
45898
|
+
async function issueCredential(credential, privateKey, verificationMethod) {
|
|
45899
|
+
return signWithDataIntegrity(credential, privateKey, verificationMethod, "assertionMethod");
|
|
45900
|
+
}
|
|
45901
|
+
async function presentCredentials(presentation, privateKey, verificationMethod) {
|
|
45902
|
+
return signWithDataIntegrity(presentation, privateKey, verificationMethod, "authentication");
|
|
45903
|
+
}
|
|
45904
|
+
var VC_CONTEXT_V2, AV_CREDENTIAL_CONTEXT, CRYPTOSUITE, BASE58_ALPHABET2;
|
|
45438
45905
|
var init_vc = __esm({
|
|
45439
45906
|
async "../crypto/dist/vc.js"() {
|
|
45440
45907
|
"use strict";
|
|
45908
|
+
await init_libsodium_wrappers();
|
|
45441
45909
|
await init_did();
|
|
45910
|
+
VC_CONTEXT_V2 = "https://www.w3.org/ns/credentials/v2";
|
|
45911
|
+
AV_CREDENTIAL_CONTEXT = "https://agentvault.chat/ns/credentials/v1";
|
|
45912
|
+
CRYPTOSUITE = "eddsa-jcs-2022";
|
|
45913
|
+
BASE58_ALPHABET2 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
45442
45914
|
}
|
|
45443
45915
|
});
|
|
45444
45916
|
|
|
45445
45917
|
// ../crypto/dist/transport.js
|
|
45446
|
-
function
|
|
45918
|
+
function hexToBytes2(hex3) {
|
|
45447
45919
|
return libsodium_wrappers_default.from_hex(hex3);
|
|
45448
45920
|
}
|
|
45449
|
-
function
|
|
45921
|
+
function bytesToHex2(bytes) {
|
|
45450
45922
|
return libsodium_wrappers_default.to_hex(bytes);
|
|
45451
45923
|
}
|
|
45452
45924
|
function base64ToBytes(b64) {
|
|
@@ -45484,6 +45956,70 @@ function transportToEncryptedMessage(transport) {
|
|
|
45484
45956
|
ciphertext: base64ToBytes(transport.ciphertext)
|
|
45485
45957
|
};
|
|
45486
45958
|
}
|
|
45959
|
+
function encryptedMessageToTransportV2(msg) {
|
|
45960
|
+
if (!msg.encryptedHeader || !msg.headerNonce) {
|
|
45961
|
+
throw new Error("encryptedMessageToTransportV2 requires v2 encrypted message");
|
|
45962
|
+
}
|
|
45963
|
+
return {
|
|
45964
|
+
envelope_version: "2.0.0",
|
|
45965
|
+
encrypted_header: bytesToBase64(msg.encryptedHeader),
|
|
45966
|
+
header_nonce: bytesToBase64(msg.headerNonce),
|
|
45967
|
+
header_signature: bytesToBase64(msg.headerSignature),
|
|
45968
|
+
nonce: bytesToBase64(msg.nonce),
|
|
45969
|
+
ciphertext: bytesToBase64(msg.ciphertext)
|
|
45970
|
+
};
|
|
45971
|
+
}
|
|
45972
|
+
function transportV2ToEncryptedMessage(transport, plaintextHeader) {
|
|
45973
|
+
return {
|
|
45974
|
+
header: plaintextHeader,
|
|
45975
|
+
headerSignature: base64ToBytes(transport.header_signature),
|
|
45976
|
+
ciphertext: base64ToBytes(transport.ciphertext),
|
|
45977
|
+
nonce: base64ToBytes(transport.nonce),
|
|
45978
|
+
envelopeVersion: "2.0.0",
|
|
45979
|
+
encryptedHeader: base64ToBytes(transport.encrypted_header),
|
|
45980
|
+
headerNonce: base64ToBytes(transport.header_nonce)
|
|
45981
|
+
};
|
|
45982
|
+
}
|
|
45983
|
+
function encryptedMessageToTransportV2Full(msg) {
|
|
45984
|
+
if (!msg.encryptedHeader || !msg.headerNonce) {
|
|
45985
|
+
throw new Error("encryptedMessageToTransportV2Full requires v2 encrypted message");
|
|
45986
|
+
}
|
|
45987
|
+
const v1 = encryptedMessageToTransport(msg);
|
|
45988
|
+
return {
|
|
45989
|
+
...v1,
|
|
45990
|
+
envelope_version: "2.0.0",
|
|
45991
|
+
encrypted_header: bytesToBase64(msg.encryptedHeader),
|
|
45992
|
+
header_nonce: bytesToBase64(msg.headerNonce)
|
|
45993
|
+
};
|
|
45994
|
+
}
|
|
45995
|
+
function encryptedMessageToHexTransport(msg) {
|
|
45996
|
+
const headerObj = {
|
|
45997
|
+
dhPublicKey: bytesToHex2(msg.header.dhPublicKey),
|
|
45998
|
+
previousChainLength: msg.header.previousChainLength,
|
|
45999
|
+
messageNumber: msg.header.messageNumber
|
|
46000
|
+
};
|
|
46001
|
+
const headerBlobHex = Buffer.from(JSON.stringify(headerObj)).toString("hex");
|
|
46002
|
+
return {
|
|
46003
|
+
header_blob: headerBlobHex,
|
|
46004
|
+
header_signature: bytesToHex2(msg.headerSignature),
|
|
46005
|
+
ciphertext: bytesToHex2(msg.ciphertext),
|
|
46006
|
+
nonce: bytesToHex2(msg.nonce)
|
|
46007
|
+
};
|
|
46008
|
+
}
|
|
46009
|
+
function hexTransportToEncryptedMessage(transport) {
|
|
46010
|
+
const headerJson = Buffer.from(transport.header_blob, "hex").toString("utf-8");
|
|
46011
|
+
const headerObj = JSON.parse(headerJson);
|
|
46012
|
+
return {
|
|
46013
|
+
header: {
|
|
46014
|
+
dhPublicKey: hexToBytes2(headerObj.dhPublicKey),
|
|
46015
|
+
previousChainLength: headerObj.previousChainLength,
|
|
46016
|
+
messageNumber: headerObj.messageNumber
|
|
46017
|
+
},
|
|
46018
|
+
headerSignature: hexToBytes2(transport.header_signature),
|
|
46019
|
+
ciphertext: hexToBytes2(transport.ciphertext),
|
|
46020
|
+
nonce: hexToBytes2(transport.nonce)
|
|
46021
|
+
};
|
|
46022
|
+
}
|
|
45487
46023
|
var init_transport = __esm({
|
|
45488
46024
|
async "../crypto/dist/transport.js"() {
|
|
45489
46025
|
"use strict";
|
|
@@ -45747,6 +46283,33 @@ function buildEvalSpan(opts) {
|
|
|
45747
46283
|
status: { code: 0 }
|
|
45748
46284
|
};
|
|
45749
46285
|
}
|
|
46286
|
+
function buildForgeSpan(opts) {
|
|
46287
|
+
const now = Date.now();
|
|
46288
|
+
const attributes = {
|
|
46289
|
+
"ai.agent.forge.session_id": opts.forgeSessionId,
|
|
46290
|
+
"ai.agent.forge.phase": opts.phase
|
|
46291
|
+
};
|
|
46292
|
+
if (opts.stageNumber !== void 0)
|
|
46293
|
+
attributes["ai.agent.forge.stage_number"] = opts.stageNumber;
|
|
46294
|
+
if (opts.artifactCount !== void 0)
|
|
46295
|
+
attributes["ai.agent.forge.artifact_count"] = opts.artifactCount;
|
|
46296
|
+
if (opts.scanStatus !== void 0)
|
|
46297
|
+
attributes["ai.agent.forge.scan_status"] = opts.scanStatus;
|
|
46298
|
+
applySkillName(attributes, opts.skillName);
|
|
46299
|
+
const isError = opts.status === "error";
|
|
46300
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46301
|
+
return {
|
|
46302
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46303
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46304
|
+
parentSpanId: opts.parentSpanId,
|
|
46305
|
+
name: `forge.${opts.phase}`,
|
|
46306
|
+
kind: "internal",
|
|
46307
|
+
startTime: now - opts.latencyMs,
|
|
46308
|
+
endTime: now,
|
|
46309
|
+
attributes,
|
|
46310
|
+
status
|
|
46311
|
+
};
|
|
46312
|
+
}
|
|
45750
46313
|
function buildPolicyViolationSpan(opts) {
|
|
45751
46314
|
const now = Date.now();
|
|
45752
46315
|
const attributes = {
|
|
@@ -45775,9 +46338,306 @@ function buildPolicyViolationSpan(opts) {
|
|
|
45775
46338
|
status: isBlock ? { code: 2, message: `Policy violation: ${opts.violationType}` } : { code: 0 }
|
|
45776
46339
|
};
|
|
45777
46340
|
}
|
|
46341
|
+
function buildDecisionSpan(opts) {
|
|
46342
|
+
const now = Date.now();
|
|
46343
|
+
const attributes = {
|
|
46344
|
+
"av.decision.id": opts.decisionId,
|
|
46345
|
+
"av.decision.phase": opts.phase
|
|
46346
|
+
};
|
|
46347
|
+
if (opts.priority)
|
|
46348
|
+
attributes["av.decision.priority"] = opts.priority;
|
|
46349
|
+
if (opts.category)
|
|
46350
|
+
attributes["av.decision.category"] = opts.category;
|
|
46351
|
+
applySkillName(attributes, opts.skillName);
|
|
46352
|
+
const isError = opts.status === "error";
|
|
46353
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46354
|
+
return {
|
|
46355
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46356
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46357
|
+
parentSpanId: opts.parentSpanId,
|
|
46358
|
+
name: "av.decision",
|
|
46359
|
+
kind: "internal",
|
|
46360
|
+
startTime: now - opts.latencyMs,
|
|
46361
|
+
endTime: now,
|
|
46362
|
+
attributes,
|
|
46363
|
+
status
|
|
46364
|
+
};
|
|
46365
|
+
}
|
|
46366
|
+
function buildResyncSpan(opts) {
|
|
46367
|
+
const now = Date.now();
|
|
46368
|
+
const attributes = {
|
|
46369
|
+
"av.resync.conversation_id": opts.conversationId,
|
|
46370
|
+
"av.resync.phase": opts.phase
|
|
46371
|
+
};
|
|
46372
|
+
if (opts.reason)
|
|
46373
|
+
attributes["av.resync.reason"] = opts.reason;
|
|
46374
|
+
applySkillName(attributes, opts.skillName);
|
|
46375
|
+
const isError = opts.status === "error";
|
|
46376
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46377
|
+
return {
|
|
46378
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46379
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46380
|
+
parentSpanId: opts.parentSpanId,
|
|
46381
|
+
name: "av.resync",
|
|
46382
|
+
kind: "internal",
|
|
46383
|
+
startTime: now - opts.latencyMs,
|
|
46384
|
+
endTime: now,
|
|
46385
|
+
attributes,
|
|
46386
|
+
status
|
|
46387
|
+
};
|
|
46388
|
+
}
|
|
46389
|
+
function buildA2aSpan(opts) {
|
|
46390
|
+
const now = Date.now();
|
|
46391
|
+
const attributes = {
|
|
46392
|
+
"av.a2a.channel_id": opts.channelId,
|
|
46393
|
+
"av.a2a.operation": opts.operation
|
|
46394
|
+
};
|
|
46395
|
+
if (opts.peerHubAddress)
|
|
46396
|
+
attributes["av.a2a.peer_hub_address"] = opts.peerHubAddress;
|
|
46397
|
+
if (opts.role)
|
|
46398
|
+
attributes["av.a2a.role"] = opts.role;
|
|
46399
|
+
applySkillName(attributes, opts.skillName);
|
|
46400
|
+
const isError = opts.status === "error";
|
|
46401
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46402
|
+
return {
|
|
46403
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46404
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46405
|
+
parentSpanId: opts.parentSpanId,
|
|
46406
|
+
name: "av.a2a",
|
|
46407
|
+
kind: "internal",
|
|
46408
|
+
startTime: now - opts.latencyMs,
|
|
46409
|
+
endTime: now,
|
|
46410
|
+
attributes,
|
|
46411
|
+
status
|
|
46412
|
+
};
|
|
46413
|
+
}
|
|
46414
|
+
function buildScanSpan(opts) {
|
|
46415
|
+
const now = Date.now();
|
|
46416
|
+
const attributes = {
|
|
46417
|
+
"av.scan.target": opts.scanTarget,
|
|
46418
|
+
"av.scan.type": opts.scanType,
|
|
46419
|
+
"av.scan.violation_count": opts.violationCount,
|
|
46420
|
+
"av.scan.rule_count": opts.ruleCount
|
|
46421
|
+
};
|
|
46422
|
+
applySkillName(attributes, opts.skillName);
|
|
46423
|
+
const isError = opts.status === "error" || opts.violationCount > 0;
|
|
46424
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46425
|
+
return {
|
|
46426
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46427
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46428
|
+
parentSpanId: opts.parentSpanId,
|
|
46429
|
+
name: "av.scan",
|
|
46430
|
+
kind: "internal",
|
|
46431
|
+
startTime: now - opts.latencyMs,
|
|
46432
|
+
endTime: now,
|
|
46433
|
+
attributes,
|
|
46434
|
+
status
|
|
46435
|
+
};
|
|
46436
|
+
}
|
|
46437
|
+
function buildWorkspaceSpan(opts) {
|
|
46438
|
+
const now = Date.now();
|
|
46439
|
+
const attributes = {
|
|
46440
|
+
"av.workspace.id": opts.workspaceId,
|
|
46441
|
+
"av.workspace.operation": opts.operation
|
|
46442
|
+
};
|
|
46443
|
+
if (opts.fileName)
|
|
46444
|
+
attributes["av.workspace.file_name"] = opts.fileName;
|
|
46445
|
+
if (opts.fileSizeBytes !== void 0)
|
|
46446
|
+
attributes["av.workspace.file_size_bytes"] = opts.fileSizeBytes;
|
|
46447
|
+
if (opts.encrypted !== void 0)
|
|
46448
|
+
attributes["av.workspace.encrypted"] = opts.encrypted;
|
|
46449
|
+
applySkillName(attributes, opts.skillName);
|
|
46450
|
+
const isError = opts.status === "error";
|
|
46451
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46452
|
+
return {
|
|
46453
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46454
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46455
|
+
parentSpanId: opts.parentSpanId,
|
|
46456
|
+
name: "av.workspace",
|
|
46457
|
+
kind: "internal",
|
|
46458
|
+
startTime: now - opts.latencyMs,
|
|
46459
|
+
endTime: now,
|
|
46460
|
+
attributes,
|
|
46461
|
+
status
|
|
46462
|
+
};
|
|
46463
|
+
}
|
|
46464
|
+
function buildCapabilitySpan(opts) {
|
|
46465
|
+
const now = Date.now();
|
|
46466
|
+
const attributes = {
|
|
46467
|
+
"av.skill.operation": opts.operation,
|
|
46468
|
+
"av.skill.success": opts.success
|
|
46469
|
+
};
|
|
46470
|
+
if (opts.skillName)
|
|
46471
|
+
attributes["av.skill.name"] = opts.skillName;
|
|
46472
|
+
if (opts.version)
|
|
46473
|
+
attributes["av.skill.version"] = opts.version;
|
|
46474
|
+
if (opts.certificationTier)
|
|
46475
|
+
attributes["av.skill.certification_tier"] = opts.certificationTier;
|
|
46476
|
+
if (opts.toolsUsed?.length)
|
|
46477
|
+
attributes["av.skill.tools_used"] = opts.toolsUsed.join(",");
|
|
46478
|
+
const status = opts.success ? { code: 0 } : { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} };
|
|
46479
|
+
return {
|
|
46480
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46481
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46482
|
+
parentSpanId: opts.parentSpanId,
|
|
46483
|
+
name: "av.skill.invoke",
|
|
46484
|
+
kind: "internal",
|
|
46485
|
+
startTime: now - opts.latencyMs,
|
|
46486
|
+
endTime: now,
|
|
46487
|
+
attributes,
|
|
46488
|
+
status
|
|
46489
|
+
};
|
|
46490
|
+
}
|
|
46491
|
+
function buildEnrollmentSpan(opts) {
|
|
46492
|
+
const now = Date.now();
|
|
46493
|
+
const attributes = {
|
|
46494
|
+
"av.enrollment.phase": opts.phase
|
|
46495
|
+
};
|
|
46496
|
+
if (opts.deviceId)
|
|
46497
|
+
attributes["av.enrollment.device_id"] = opts.deviceId;
|
|
46498
|
+
if (opts.enrollmentType)
|
|
46499
|
+
attributes["av.enrollment.type"] = opts.enrollmentType;
|
|
46500
|
+
applySkillName(attributes, opts.skillName);
|
|
46501
|
+
const isError = opts.status === "error" || opts.phase === "fail";
|
|
46502
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46503
|
+
return {
|
|
46504
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46505
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46506
|
+
parentSpanId: opts.parentSpanId,
|
|
46507
|
+
name: "av.enrollment",
|
|
46508
|
+
kind: "internal",
|
|
46509
|
+
startTime: now - opts.latencyMs,
|
|
46510
|
+
endTime: now,
|
|
46511
|
+
attributes,
|
|
46512
|
+
status
|
|
46513
|
+
};
|
|
46514
|
+
}
|
|
46515
|
+
function buildRoomSpan(opts) {
|
|
46516
|
+
const now = Date.now();
|
|
46517
|
+
const attributes = {
|
|
46518
|
+
"av.room.id": opts.roomId,
|
|
46519
|
+
"av.room.operation": opts.operation
|
|
46520
|
+
};
|
|
46521
|
+
if (opts.roomName)
|
|
46522
|
+
attributes["av.room.name"] = opts.roomName;
|
|
46523
|
+
if (opts.memberCount !== void 0)
|
|
46524
|
+
attributes["av.room.member_count"] = opts.memberCount;
|
|
46525
|
+
applySkillName(attributes, opts.skillName);
|
|
46526
|
+
const isError = opts.status === "error";
|
|
46527
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46528
|
+
return {
|
|
46529
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46530
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46531
|
+
parentSpanId: opts.parentSpanId,
|
|
46532
|
+
name: "av.room",
|
|
46533
|
+
kind: "internal",
|
|
46534
|
+
startTime: now - opts.latencyMs,
|
|
46535
|
+
endTime: now,
|
|
46536
|
+
attributes,
|
|
46537
|
+
status
|
|
46538
|
+
};
|
|
46539
|
+
}
|
|
46540
|
+
function buildTrustSpan(opts) {
|
|
46541
|
+
const now = Date.now();
|
|
46542
|
+
const attributes = {
|
|
46543
|
+
"av.trust.agent_hub_address": opts.agentHubAddress,
|
|
46544
|
+
"av.trust.operation": opts.operation
|
|
46545
|
+
};
|
|
46546
|
+
if (opts.previousTier)
|
|
46547
|
+
attributes["av.trust.previous_tier"] = opts.previousTier;
|
|
46548
|
+
if (opts.newTier)
|
|
46549
|
+
attributes["av.trust.new_tier"] = opts.newTier;
|
|
46550
|
+
if (opts.overallScore !== void 0)
|
|
46551
|
+
attributes["av.trust.overall_score"] = opts.overallScore;
|
|
46552
|
+
if (opts.dimension)
|
|
46553
|
+
attributes["av.trust.dimension"] = opts.dimension;
|
|
46554
|
+
if (opts.dimensionScore !== void 0)
|
|
46555
|
+
attributes["av.trust.dimension_score"] = opts.dimensionScore;
|
|
46556
|
+
applySkillName(attributes, opts.skillName);
|
|
46557
|
+
const isError = opts.status === "error";
|
|
46558
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46559
|
+
return {
|
|
46560
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46561
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46562
|
+
parentSpanId: opts.parentSpanId,
|
|
46563
|
+
name: "av.trust",
|
|
46564
|
+
kind: "internal",
|
|
46565
|
+
startTime: now - opts.latencyMs,
|
|
46566
|
+
endTime: now,
|
|
46567
|
+
attributes,
|
|
46568
|
+
status
|
|
46569
|
+
};
|
|
46570
|
+
}
|
|
46571
|
+
function buildEvalRunSpan(opts) {
|
|
46572
|
+
const now = Date.now();
|
|
46573
|
+
const attributes = {
|
|
46574
|
+
"av.eval.scenario_id": opts.scenarioId,
|
|
46575
|
+
"av.eval.agent_id": opts.agentId,
|
|
46576
|
+
"av.eval.status": opts.status,
|
|
46577
|
+
"av.eval.latency_ms": opts.latencyMs
|
|
46578
|
+
};
|
|
46579
|
+
if (opts.scenarioName)
|
|
46580
|
+
attributes["av.eval.scenario_name"] = opts.scenarioName;
|
|
46581
|
+
if (opts.variationType)
|
|
46582
|
+
attributes["av.eval.variation_type"] = opts.variationType;
|
|
46583
|
+
if (opts.shiftMagnitude !== void 0)
|
|
46584
|
+
attributes["av.eval.shift_magnitude"] = opts.shiftMagnitude;
|
|
46585
|
+
if (opts.outcomeMatch !== void 0)
|
|
46586
|
+
attributes["av.eval.outcome_match"] = opts.outcomeMatch;
|
|
46587
|
+
if (opts.flagged !== void 0)
|
|
46588
|
+
attributes["av.eval.flagged"] = opts.flagged;
|
|
46589
|
+
if (opts.flagReason)
|
|
46590
|
+
attributes["av.eval.flag_reason"] = opts.flagReason;
|
|
46591
|
+
const isError = opts.status === "failed";
|
|
46592
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
46593
|
+
return {
|
|
46594
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
46595
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
46596
|
+
parentSpanId: opts.parentSpanId,
|
|
46597
|
+
name: "av.eval.run",
|
|
46598
|
+
kind: "internal",
|
|
46599
|
+
startTime: now - opts.latencyMs,
|
|
46600
|
+
endTime: now,
|
|
46601
|
+
attributes,
|
|
46602
|
+
status
|
|
46603
|
+
};
|
|
46604
|
+
}
|
|
45778
46605
|
function buildTraceparent(span) {
|
|
45779
46606
|
return `00-${span.traceId}-${span.spanId}-01`;
|
|
45780
46607
|
}
|
|
46608
|
+
function parseTraceparent(header) {
|
|
46609
|
+
const parts = header.split("-");
|
|
46610
|
+
if (parts.length !== 4)
|
|
46611
|
+
return null;
|
|
46612
|
+
const [version2, traceId, parentId, traceFlags] = parts;
|
|
46613
|
+
if (!version2 || !traceId || !parentId || !traceFlags)
|
|
46614
|
+
return null;
|
|
46615
|
+
if (traceId.length !== 32 || parentId.length !== 16)
|
|
46616
|
+
return null;
|
|
46617
|
+
return { version: version2, traceId, parentId, traceFlags };
|
|
46618
|
+
}
|
|
46619
|
+
function spanToTraceContext(span, tracestate) {
|
|
46620
|
+
return {
|
|
46621
|
+
traceparent: buildTraceparent(span),
|
|
46622
|
+
tracestate: tracestate ?? `av=s:${span.spanId}`
|
|
46623
|
+
};
|
|
46624
|
+
}
|
|
46625
|
+
function propagateContext(incomingTraceparent) {
|
|
46626
|
+
const parsed = parseTraceparent(incomingTraceparent);
|
|
46627
|
+
if (!parsed)
|
|
46628
|
+
return null;
|
|
46629
|
+
return {
|
|
46630
|
+
traceId: parsed.traceId,
|
|
46631
|
+
parentSpanId: parsed.parentId,
|
|
46632
|
+
spanId: generateSpanId()
|
|
46633
|
+
};
|
|
46634
|
+
}
|
|
46635
|
+
function spanToW3CHeaders(span, tracestate) {
|
|
46636
|
+
return {
|
|
46637
|
+
traceparent: buildTraceparent(span),
|
|
46638
|
+
tracestate: tracestate ?? `av=s:${span.spanId}`
|
|
46639
|
+
};
|
|
46640
|
+
}
|
|
45781
46641
|
var init_telemetry = __esm({
|
|
45782
46642
|
"../crypto/dist/telemetry.js"() {
|
|
45783
46643
|
"use strict";
|
|
@@ -45948,6 +46808,29 @@ var init_telemetry_reporter = __esm({
|
|
|
45948
46808
|
});
|
|
45949
46809
|
|
|
45950
46810
|
// ../crypto/dist/backup.js
|
|
46811
|
+
async function generateBackupCode() {
|
|
46812
|
+
await libsodium_wrappers_default.ready;
|
|
46813
|
+
const bytes = libsodium_wrappers_default.randombytes_buf(13);
|
|
46814
|
+
let bits = 0n;
|
|
46815
|
+
for (const b2 of bytes) {
|
|
46816
|
+
bits = bits << 8n | BigInt(b2);
|
|
46817
|
+
}
|
|
46818
|
+
bits >>= 4n;
|
|
46819
|
+
let code = "";
|
|
46820
|
+
for (let i2 = 0; i2 < 20; i2++) {
|
|
46821
|
+
const idx = Number(bits & 0x1fn);
|
|
46822
|
+
code = CROCKFORD[idx] + code;
|
|
46823
|
+
bits >>= 5n;
|
|
46824
|
+
}
|
|
46825
|
+
return code;
|
|
46826
|
+
}
|
|
46827
|
+
function formatBackupCode(code) {
|
|
46828
|
+
const clean5 = code.replace(/[-\s]/g, "").toUpperCase();
|
|
46829
|
+
return clean5.match(/.{1,4}/g)?.join("-") ?? clean5;
|
|
46830
|
+
}
|
|
46831
|
+
function normalizeBackupCode(input) {
|
|
46832
|
+
return input.replace(/[-\s]/g, "").toUpperCase();
|
|
46833
|
+
}
|
|
45951
46834
|
async function deriveBackupKey(code, salt) {
|
|
45952
46835
|
await libsodium_wrappers_default.ready;
|
|
45953
46836
|
return libsodium_wrappers_default.crypto_pwhash(KEY_BYTES, code, salt, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, libsodium_wrappers_default.crypto_pwhash_ALG_ARGON2ID13);
|
|
@@ -45969,28 +46852,88 @@ async function encryptBackupWithKey(bundle, key, salt) {
|
|
|
45969
46852
|
result.set(ciphertext, SALT_BYTES + NONCE_BYTES);
|
|
45970
46853
|
return result;
|
|
45971
46854
|
}
|
|
46855
|
+
async function decryptBackup(encrypted, code) {
|
|
46856
|
+
await libsodium_wrappers_default.ready;
|
|
46857
|
+
const minLen = SALT_BYTES + NONCE_BYTES + libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_ABYTES;
|
|
46858
|
+
if (encrypted.length < minLen) {
|
|
46859
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46860
|
+
}
|
|
46861
|
+
const salt = encrypted.slice(0, SALT_BYTES);
|
|
46862
|
+
const nonce = encrypted.slice(SALT_BYTES, SALT_BYTES + NONCE_BYTES);
|
|
46863
|
+
const ciphertext = encrypted.slice(SALT_BYTES + NONCE_BYTES);
|
|
46864
|
+
const key = await deriveBackupKey(code, salt);
|
|
46865
|
+
let plaintext;
|
|
46866
|
+
try {
|
|
46867
|
+
plaintext = libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_decrypt(null, ciphertext, null, nonce, key);
|
|
46868
|
+
} catch {
|
|
46869
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46870
|
+
}
|
|
46871
|
+
let bundle;
|
|
46872
|
+
try {
|
|
46873
|
+
bundle = JSON.parse(libsodium_wrappers_default.to_string(plaintext));
|
|
46874
|
+
} catch {
|
|
46875
|
+
throw new Error("Incorrect backup code or corrupt backup");
|
|
46876
|
+
}
|
|
46877
|
+
if (bundle.version !== BACKUP_VERSION) {
|
|
46878
|
+
throw new Error(`Unsupported backup version: ${bundle.version}`);
|
|
46879
|
+
}
|
|
46880
|
+
return bundle;
|
|
46881
|
+
}
|
|
45972
46882
|
async function hashBackupCode(code) {
|
|
45973
46883
|
await libsodium_wrappers_default.ready;
|
|
45974
46884
|
return libsodium_wrappers_default.crypto_generichash(32, libsodium_wrappers_default.from_string(code));
|
|
45975
46885
|
}
|
|
45976
|
-
var ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, MAX_BACKUP_SIZE;
|
|
46886
|
+
var CROCKFORD, ARGON2_OPSLIMIT, ARGON2_MEMLIMIT, SALT_BYTES, NONCE_BYTES, KEY_BYTES, BACKUP_VERSION, MAX_BACKUP_SIZE;
|
|
45977
46887
|
var init_backup = __esm({
|
|
45978
46888
|
async "../crypto/dist/backup.js"() {
|
|
45979
46889
|
"use strict";
|
|
45980
46890
|
await init_libsodium_wrappers();
|
|
46891
|
+
CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
45981
46892
|
ARGON2_OPSLIMIT = 2;
|
|
45982
46893
|
ARGON2_MEMLIMIT = 67108864;
|
|
45983
46894
|
SALT_BYTES = 16;
|
|
45984
46895
|
NONCE_BYTES = 24;
|
|
45985
46896
|
KEY_BYTES = 32;
|
|
46897
|
+
BACKUP_VERSION = 1;
|
|
45986
46898
|
MAX_BACKUP_SIZE = 512 * 1024;
|
|
45987
46899
|
}
|
|
45988
46900
|
});
|
|
45989
46901
|
|
|
45990
46902
|
// ../crypto/dist/approval.js
|
|
46903
|
+
async function createApprovalArtifact(content, privateKeyHex) {
|
|
46904
|
+
await libsodium_wrappers_default.ready;
|
|
46905
|
+
const sodium = libsodium_wrappers_default;
|
|
46906
|
+
const privateKey = sodium.from_hex(privateKeyHex);
|
|
46907
|
+
const publicKey = privateKey.slice(32);
|
|
46908
|
+
const message = canonicalize(content);
|
|
46909
|
+
const signatureBytes = sodium.crypto_sign_detached(message, privateKey);
|
|
46910
|
+
return {
|
|
46911
|
+
content,
|
|
46912
|
+
signature: sodium.to_hex(signatureBytes),
|
|
46913
|
+
signerPublicKey: sodium.to_hex(publicKey),
|
|
46914
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46915
|
+
version: 1
|
|
46916
|
+
};
|
|
46917
|
+
}
|
|
46918
|
+
async function verifyApprovalArtifact(artifact, expectedPublicKeyHex) {
|
|
46919
|
+
await libsodium_wrappers_default.ready;
|
|
46920
|
+
const sodium = libsodium_wrappers_default;
|
|
46921
|
+
if (expectedPublicKeyHex && artifact.signerPublicKey !== expectedPublicKeyHex) {
|
|
46922
|
+
return false;
|
|
46923
|
+
}
|
|
46924
|
+
try {
|
|
46925
|
+
const publicKey = sodium.from_hex(artifact.signerPublicKey);
|
|
46926
|
+
const signature = sodium.from_hex(artifact.signature);
|
|
46927
|
+
const message = canonicalize(artifact.content);
|
|
46928
|
+
return sodium.crypto_sign_verify_detached(signature, message, publicKey);
|
|
46929
|
+
} catch {
|
|
46930
|
+
return false;
|
|
46931
|
+
}
|
|
46932
|
+
}
|
|
45991
46933
|
var init_approval = __esm({
|
|
45992
46934
|
async "../crypto/dist/approval.js"() {
|
|
45993
46935
|
"use strict";
|
|
46936
|
+
await init_libsodium_wrappers();
|
|
45994
46937
|
await init_did();
|
|
45995
46938
|
}
|
|
45996
46939
|
});
|
|
@@ -54937,7 +55880,7 @@ function byteSwap32(arr) {
|
|
|
54937
55880
|
}
|
|
54938
55881
|
return arr;
|
|
54939
55882
|
}
|
|
54940
|
-
function
|
|
55883
|
+
function bytesToHex4(bytes) {
|
|
54941
55884
|
abytes3(bytes);
|
|
54942
55885
|
if (hasHexBuiltin)
|
|
54943
55886
|
return bytes.toHex();
|
|
@@ -54956,7 +55899,7 @@ function asciiToBase16(ch) {
|
|
|
54956
55899
|
return ch - (asciis.a - 10);
|
|
54957
55900
|
return;
|
|
54958
55901
|
}
|
|
54959
|
-
function
|
|
55902
|
+
function hexToBytes4(hex3) {
|
|
54960
55903
|
if (typeof hex3 !== "string")
|
|
54961
55904
|
throw new Error("hex string expected, got " + typeof hex3);
|
|
54962
55905
|
if (hasHexBuiltin)
|
|
@@ -55252,7 +56195,7 @@ var init_u642 = __esm({
|
|
|
55252
56195
|
});
|
|
55253
56196
|
|
|
55254
56197
|
// ../../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha2.js
|
|
55255
|
-
var SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384,
|
|
56198
|
+
var SHA256_K, SHA256_W, SHA256, K512, SHA512_Kh, SHA512_Kl, SHA512_W_H, SHA512_W_L, SHA512, SHA384, sha2563, sha5122, sha3842;
|
|
55256
56199
|
var init_sha22 = __esm({
|
|
55257
56200
|
"../../node_modules/@noble/curves/node_modules/@noble/hashes/esm/sha2.js"() {
|
|
55258
56201
|
init_md2();
|
|
@@ -55613,7 +56556,7 @@ var init_sha22 = __esm({
|
|
|
55613
56556
|
this.Hl = SHA384_IV2[15] | 0;
|
|
55614
56557
|
}
|
|
55615
56558
|
};
|
|
55616
|
-
|
|
56559
|
+
sha2563 = /* @__PURE__ */ createHasher2(() => new SHA256());
|
|
55617
56560
|
sha5122 = /* @__PURE__ */ createHasher2(() => new SHA512());
|
|
55618
56561
|
sha3842 = /* @__PURE__ */ createHasher2(() => new SHA384());
|
|
55619
56562
|
}
|
|
@@ -55649,14 +56592,14 @@ function hexToNumber3(hex3) {
|
|
|
55649
56592
|
return hex3 === "" ? _0n2 : BigInt("0x" + hex3);
|
|
55650
56593
|
}
|
|
55651
56594
|
function bytesToNumberBE(bytes) {
|
|
55652
|
-
return hexToNumber3(
|
|
56595
|
+
return hexToNumber3(bytesToHex4(bytes));
|
|
55653
56596
|
}
|
|
55654
56597
|
function bytesToNumberLE2(bytes) {
|
|
55655
56598
|
abytes3(bytes);
|
|
55656
|
-
return hexToNumber3(
|
|
56599
|
+
return hexToNumber3(bytesToHex4(Uint8Array.from(bytes).reverse()));
|
|
55657
56600
|
}
|
|
55658
56601
|
function numberToBytesBE2(n2, len) {
|
|
55659
|
-
return
|
|
56602
|
+
return hexToBytes4(n2.toString(16).padStart(len * 2, "0"));
|
|
55660
56603
|
}
|
|
55661
56604
|
function numberToBytesLE2(n2, len) {
|
|
55662
56605
|
return numberToBytesBE2(n2, len).reverse();
|
|
@@ -55665,7 +56608,7 @@ function ensureBytes(title, hex3, expectedLength) {
|
|
|
55665
56608
|
let res;
|
|
55666
56609
|
if (typeof hex3 === "string") {
|
|
55667
56610
|
try {
|
|
55668
|
-
res =
|
|
56611
|
+
res = hexToBytes4(hex3);
|
|
55669
56612
|
} catch (e) {
|
|
55670
56613
|
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
55671
56614
|
}
|
|
@@ -56693,7 +57636,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
56693
57636
|
return bytes;
|
|
56694
57637
|
}
|
|
56695
57638
|
toHex() {
|
|
56696
|
-
return
|
|
57639
|
+
return bytesToHex4(this.toBytes());
|
|
56697
57640
|
}
|
|
56698
57641
|
toString() {
|
|
56699
57642
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -56965,7 +57908,7 @@ var init_edwards = __esm({
|
|
|
56965
57908
|
return this.ep.toAffine(invertedZ);
|
|
56966
57909
|
}
|
|
56967
57910
|
toHex() {
|
|
56968
|
-
return
|
|
57911
|
+
return bytesToHex4(this.toBytes());
|
|
56969
57912
|
}
|
|
56970
57913
|
toString() {
|
|
56971
57914
|
return this.toHex();
|
|
@@ -58766,7 +59709,7 @@ function weierstrassN(params, extraOpts = {}) {
|
|
|
58766
59709
|
return encodePoint(Point, this, isCompressed);
|
|
58767
59710
|
}
|
|
58768
59711
|
toHex(isCompressed = true) {
|
|
58769
|
-
return
|
|
59712
|
+
return bytesToHex4(this.toBytes(isCompressed));
|
|
58770
59713
|
}
|
|
58771
59714
|
toString() {
|
|
58772
59715
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
@@ -59050,7 +59993,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59050
59993
|
return new Signature(Fn3.fromBytes(r2), Fn3.fromBytes(s2), recid);
|
|
59051
59994
|
}
|
|
59052
59995
|
static fromHex(hex3, format) {
|
|
59053
|
-
return this.fromBytes(
|
|
59996
|
+
return this.fromBytes(hexToBytes4(hex3), format);
|
|
59054
59997
|
}
|
|
59055
59998
|
addRecoveryBit(recovery) {
|
|
59056
59999
|
return new Signature(this.r, this.s, recovery);
|
|
@@ -59085,7 +60028,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59085
60028
|
toBytes(format = defaultSigOpts_format) {
|
|
59086
60029
|
validateSigFormat(format);
|
|
59087
60030
|
if (format === "der")
|
|
59088
|
-
return
|
|
60031
|
+
return hexToBytes4(DER.hexFromSig(this));
|
|
59089
60032
|
const r2 = Fn3.toBytes(this.r);
|
|
59090
60033
|
const s2 = Fn3.toBytes(this.s);
|
|
59091
60034
|
if (format === "recovered") {
|
|
@@ -59096,7 +60039,7 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59096
60039
|
return concatBytes2(r2, s2);
|
|
59097
60040
|
}
|
|
59098
60041
|
toHex(format) {
|
|
59099
|
-
return
|
|
60042
|
+
return bytesToHex4(this.toBytes(format));
|
|
59100
60043
|
}
|
|
59101
60044
|
// TODO: remove
|
|
59102
60045
|
assertValidity() {
|
|
@@ -59114,13 +60057,13 @@ function ecdsa(Point, hash2, ecdsaOpts = {}) {
|
|
|
59114
60057
|
return this.toBytes("der");
|
|
59115
60058
|
}
|
|
59116
60059
|
toDERHex() {
|
|
59117
|
-
return
|
|
60060
|
+
return bytesToHex4(this.toBytes("der"));
|
|
59118
60061
|
}
|
|
59119
60062
|
toCompactRawBytes() {
|
|
59120
60063
|
return this.toBytes("compact");
|
|
59121
60064
|
}
|
|
59122
60065
|
toCompactHex() {
|
|
59123
|
-
return
|
|
60066
|
+
return bytesToHex4(this.toBytes("compact"));
|
|
59124
60067
|
}
|
|
59125
60068
|
}
|
|
59126
60069
|
const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes) {
|
|
@@ -59499,7 +60442,7 @@ var init_nist = __esm({
|
|
|
59499
60442
|
Fp256 = Field(p256_CURVE.p);
|
|
59500
60443
|
Fp384 = Field(p384_CURVE.p);
|
|
59501
60444
|
Fp521 = Field(p521_CURVE.p);
|
|
59502
|
-
p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false },
|
|
60445
|
+
p256 = createCurve({ ...p256_CURVE, Fp: Fp256, lowS: false }, sha2563);
|
|
59503
60446
|
p256_hasher = /* @__PURE__ */ (() => {
|
|
59504
60447
|
return createHasher3(p256.Point, createSWU(p256.Point, {
|
|
59505
60448
|
A: p256_CURVE.a,
|
|
@@ -59512,7 +60455,7 @@ var init_nist = __esm({
|
|
|
59512
60455
|
m: 1,
|
|
59513
60456
|
k: 128,
|
|
59514
60457
|
expand: "xmd",
|
|
59515
|
-
hash:
|
|
60458
|
+
hash: sha2563
|
|
59516
60459
|
});
|
|
59517
60460
|
})();
|
|
59518
60461
|
p384 = createCurve({ ...p384_CURVE, Fp: Fp384, lowS: false }, sha3842);
|
|
@@ -60020,7 +60963,7 @@ var init_u643 = __esm({
|
|
|
60020
60963
|
});
|
|
60021
60964
|
|
|
60022
60965
|
// ../crypto/node_modules/@noble/hashes/sha2.js
|
|
60023
|
-
var SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384,
|
|
60966
|
+
var SHA256_K2, SHA256_W2, SHA2_32B, _SHA256, K5122, SHA512_Kh2, SHA512_Kl2, SHA512_W_H2, SHA512_W_L2, SHA2_64B, _SHA512, _SHA384, sha2564, sha5123, sha3843;
|
|
60024
60967
|
var init_sha23 = __esm({
|
|
60025
60968
|
"../crypto/node_modules/@noble/hashes/sha2.js"() {
|
|
60026
60969
|
init_md3();
|
|
@@ -60393,7 +61336,7 @@ var init_sha23 = __esm({
|
|
|
60393
61336
|
super(48);
|
|
60394
61337
|
}
|
|
60395
61338
|
};
|
|
60396
|
-
|
|
61339
|
+
sha2564 = /* @__PURE__ */ createHasher4(
|
|
60397
61340
|
() => new _SHA256(),
|
|
60398
61341
|
/* @__PURE__ */ oidNist2(1)
|
|
60399
61342
|
);
|
|
@@ -60491,7 +61434,7 @@ function makeHashImpl2(h2) {
|
|
|
60491
61434
|
async digest(data) {
|
|
60492
61435
|
switch (h2) {
|
|
60493
61436
|
case "SHA-256":
|
|
60494
|
-
return
|
|
61437
|
+
return sha2564(data);
|
|
60495
61438
|
case "SHA-384":
|
|
60496
61439
|
return sha3843(data);
|
|
60497
61440
|
case "SHA-512":
|
|
@@ -60503,7 +61446,7 @@ function makeHashImpl2(h2) {
|
|
|
60503
61446
|
async mac(key, data) {
|
|
60504
61447
|
switch (h2) {
|
|
60505
61448
|
case "SHA-256":
|
|
60506
|
-
return hmac3(
|
|
61449
|
+
return hmac3(sha2564, key, data);
|
|
60507
61450
|
case "SHA-384":
|
|
60508
61451
|
return hmac3(sha3843, key, data);
|
|
60509
61452
|
case "SHA-512":
|
|
@@ -61670,6 +62613,92 @@ var init_mls_group = __esm({
|
|
|
61670
62613
|
});
|
|
61671
62614
|
|
|
61672
62615
|
// ../crypto/dist/index.js
|
|
62616
|
+
var dist_exports = {};
|
|
62617
|
+
__export(dist_exports, {
|
|
62618
|
+
AV_CREDENTIAL_CONTEXT: () => AV_CREDENTIAL_CONTEXT,
|
|
62619
|
+
CRYPTOSUITE: () => CRYPTOSUITE,
|
|
62620
|
+
DOMAIN_DID_DOCUMENT: () => DOMAIN_DID_DOCUMENT,
|
|
62621
|
+
DOMAIN_TRANSFER_ACCEPT: () => DOMAIN_TRANSFER_ACCEPT,
|
|
62622
|
+
DOMAIN_TRANSFER_INTENT: () => DOMAIN_TRANSFER_INTENT,
|
|
62623
|
+
DoubleRatchet: () => DoubleRatchet,
|
|
62624
|
+
MLSGroupManager: () => MLSGroupManager,
|
|
62625
|
+
ScanEngine: () => ScanEngine,
|
|
62626
|
+
TelemetryReporter: () => TelemetryReporter,
|
|
62627
|
+
VC_CONTEXT_V2: () => VC_CONTEXT_V2,
|
|
62628
|
+
base64ToBytes: () => base64ToBytes,
|
|
62629
|
+
buildA2aSpan: () => buildA2aSpan,
|
|
62630
|
+
buildActionSpan: () => buildActionSpan,
|
|
62631
|
+
buildAgentTrustCredential: () => buildAgentTrustCredential,
|
|
62632
|
+
buildAgentTrustReportCredential: () => buildAgentTrustReportCredential,
|
|
62633
|
+
buildCapabilitySpan: () => buildCapabilitySpan,
|
|
62634
|
+
buildDecisionSpan: () => buildDecisionSpan,
|
|
62635
|
+
buildDidDocument: () => buildDidDocument,
|
|
62636
|
+
buildEnrollmentSpan: () => buildEnrollmentSpan,
|
|
62637
|
+
buildErrorSpan: () => buildErrorSpan,
|
|
62638
|
+
buildEvalRunSpan: () => buildEvalRunSpan,
|
|
62639
|
+
buildEvalSpan: () => buildEvalSpan,
|
|
62640
|
+
buildForgeSpan: () => buildForgeSpan,
|
|
62641
|
+
buildHttpSpan: () => buildHttpSpan,
|
|
62642
|
+
buildLlmSpan: () => buildLlmSpan,
|
|
62643
|
+
buildNavSpan: () => buildNavSpan,
|
|
62644
|
+
buildPerformanceRecord: () => buildPerformanceRecord,
|
|
62645
|
+
buildPolicyViolationSpan: () => buildPolicyViolationSpan,
|
|
62646
|
+
buildResyncSpan: () => buildResyncSpan,
|
|
62647
|
+
buildRoomSpan: () => buildRoomSpan,
|
|
62648
|
+
buildScanSpan: () => buildScanSpan,
|
|
62649
|
+
buildSkillAttestation: () => buildSkillAttestation,
|
|
62650
|
+
buildSkillInvocationSpan: () => buildSkillInvocationSpan,
|
|
62651
|
+
buildTaskSpan: () => buildTaskSpan,
|
|
62652
|
+
buildToolSpan: () => buildToolSpan,
|
|
62653
|
+
buildTraceparent: () => buildTraceparent,
|
|
62654
|
+
buildTrustSpan: () => buildTrustSpan,
|
|
62655
|
+
buildVerifiablePresentation: () => buildVerifiablePresentation,
|
|
62656
|
+
buildWorkspaceSpan: () => buildWorkspaceSpan,
|
|
62657
|
+
bytesToBase64: () => bytesToBase64,
|
|
62658
|
+
bytesToHex: () => bytesToHex2,
|
|
62659
|
+
canonicalize: () => canonicalize,
|
|
62660
|
+
computeDidHash: () => computeDidHash,
|
|
62661
|
+
computeFileDigest: () => computeFileDigest,
|
|
62662
|
+
computeFingerprint: () => computeFingerprint,
|
|
62663
|
+
createApprovalArtifact: () => createApprovalArtifact,
|
|
62664
|
+
createProofOfPossession: () => createProofOfPossession,
|
|
62665
|
+
decryptBackup: () => decryptBackup,
|
|
62666
|
+
decryptFile: () => decryptFile,
|
|
62667
|
+
deriveBackupKey: () => deriveBackupKey,
|
|
62668
|
+
encryptBackup: () => encryptBackup,
|
|
62669
|
+
encryptBackupWithKey: () => encryptBackupWithKey,
|
|
62670
|
+
encryptFile: () => encryptFile,
|
|
62671
|
+
encryptedMessageToHexTransport: () => encryptedMessageToHexTransport,
|
|
62672
|
+
encryptedMessageToTransport: () => encryptedMessageToTransport,
|
|
62673
|
+
encryptedMessageToTransportV2: () => encryptedMessageToTransportV2,
|
|
62674
|
+
encryptedMessageToTransportV2Full: () => encryptedMessageToTransportV2Full,
|
|
62675
|
+
formatBackupCode: () => formatBackupCode,
|
|
62676
|
+
generateBackupCode: () => generateBackupCode,
|
|
62677
|
+
generateEphemeralKeypair: () => generateEphemeralKeypair,
|
|
62678
|
+
generateIdentityKeypair: () => generateIdentityKeypair,
|
|
62679
|
+
hashBackupCode: () => hashBackupCode,
|
|
62680
|
+
hexToBytes: () => hexToBytes2,
|
|
62681
|
+
hexTransportToEncryptedMessage: () => hexTransportToEncryptedMessage,
|
|
62682
|
+
issueCredential: () => issueCredential,
|
|
62683
|
+
multibaseToPublicKey: () => multibaseToPublicKey,
|
|
62684
|
+
normalizeBackupCode: () => normalizeBackupCode,
|
|
62685
|
+
parseTraceparent: () => parseTraceparent,
|
|
62686
|
+
performX3DH: () => performX3DH,
|
|
62687
|
+
presentCredentials: () => presentCredentials,
|
|
62688
|
+
propagateContext: () => propagateContext,
|
|
62689
|
+
publicKeyToMultibase: () => publicKeyToMultibase,
|
|
62690
|
+
signDocument: () => signDocument,
|
|
62691
|
+
signWithDataIntegrity: () => signWithDataIntegrity,
|
|
62692
|
+
spanToTraceContext: () => spanToTraceContext,
|
|
62693
|
+
spanToW3CHeaders: () => spanToW3CHeaders,
|
|
62694
|
+
transportToEncryptedMessage: () => transportToEncryptedMessage,
|
|
62695
|
+
transportV2ToEncryptedMessage: () => transportV2ToEncryptedMessage,
|
|
62696
|
+
verifyApprovalArtifact: () => verifyApprovalArtifact,
|
|
62697
|
+
verifyDataIntegrity: () => verifyDataIntegrity,
|
|
62698
|
+
verifyDocumentSignature: () => verifyDocumentSignature,
|
|
62699
|
+
verifyMerkleProof: () => verifyMerkleProof,
|
|
62700
|
+
verifyProofOfPossession: () => verifyProofOfPossession
|
|
62701
|
+
});
|
|
61673
62702
|
var init_dist = __esm({
|
|
61674
62703
|
async "../crypto/dist/index.js"() {
|
|
61675
62704
|
"use strict";
|
|
@@ -61960,7 +62989,7 @@ async function uploadBackupToServer(state, backupCode, apiUrl, deviceJwt) {
|
|
|
61960
62989
|
},
|
|
61961
62990
|
body: JSON.stringify({
|
|
61962
62991
|
backup_blob: bytesToBase64(encrypted),
|
|
61963
|
-
backup_code_hash:
|
|
62992
|
+
backup_code_hash: bytesToHex2(codeHash)
|
|
61964
62993
|
})
|
|
61965
62994
|
});
|
|
61966
62995
|
if (!resp.ok) {
|
|
@@ -62533,7 +63562,7 @@ function migratePersistedState(raw) {
|
|
|
62533
63562
|
messageHistory: []
|
|
62534
63563
|
};
|
|
62535
63564
|
}
|
|
62536
|
-
var ROOM_AGENT_TYPES, CREDENTIAL_MESSAGE_TYPES, POLL_INTERVAL_MS, RECONNECT_BASE_MS, RECONNECT_MAX_MS, PENDING_POLL_INTERVAL_MS, SecureChannel;
|
|
63565
|
+
var ROOM_AGENT_TYPES, CREDENTIAL_MESSAGE_TYPES, CATCHUP_MESSAGE_TYPES, POLL_INTERVAL_MS, RECONNECT_BASE_MS, RECONNECT_MAX_MS, PENDING_POLL_INTERVAL_MS, SecureChannel;
|
|
62537
63566
|
var init_channel = __esm({
|
|
62538
63567
|
async "src/channel.ts"() {
|
|
62539
63568
|
"use strict";
|
|
@@ -62556,6 +63585,10 @@ var init_channel = __esm({
|
|
|
62556
63585
|
"credential_revoke",
|
|
62557
63586
|
"credential_request"
|
|
62558
63587
|
]);
|
|
63588
|
+
CATCHUP_MESSAGE_TYPES = /* @__PURE__ */ new Set([
|
|
63589
|
+
"history_catchup_request",
|
|
63590
|
+
"history_catchup_response"
|
|
63591
|
+
]);
|
|
62559
63592
|
POLL_INTERVAL_MS = 6e3;
|
|
62560
63593
|
RECONNECT_BASE_MS = 1e3;
|
|
62561
63594
|
RECONNECT_MAX_MS = 3e4;
|
|
@@ -62604,6 +63637,8 @@ var init_channel = __esm({
|
|
|
62604
63637
|
_mlsGroups = /* @__PURE__ */ new Map();
|
|
62605
63638
|
/** Cached MLS KeyPackage bundle for this device (regenerated on each connect). */
|
|
62606
63639
|
_mlsKeyPackage = null;
|
|
63640
|
+
/** Pending KeyPackage bundle from request-Welcome flow (used by _handleMlsWelcome). */
|
|
63641
|
+
_pendingMlsKpBundle;
|
|
62607
63642
|
/** In-memory credential store for renter-provided credentials (never persisted). */
|
|
62608
63643
|
_credentialStore = new CredentialStore();
|
|
62609
63644
|
/** Dedup buffer for A2A message IDs (prevents double-delivery via direct + Redis) */
|
|
@@ -64040,9 +65075,9 @@ var init_channel = __esm({
|
|
|
64040
65075
|
const result = await enrollDevice(
|
|
64041
65076
|
this.config.apiUrl,
|
|
64042
65077
|
this.config.inviteToken,
|
|
64043
|
-
|
|
64044
|
-
|
|
64045
|
-
|
|
65078
|
+
bytesToHex2(identity.publicKey),
|
|
65079
|
+
bytesToHex2(ephemeral.publicKey),
|
|
65080
|
+
bytesToHex2(proof),
|
|
64046
65081
|
this.config.platform
|
|
64047
65082
|
);
|
|
64048
65083
|
this._deviceId = result.device_id;
|
|
@@ -64056,12 +65091,12 @@ var init_channel = __esm({
|
|
|
64056
65091
|
sessions: {},
|
|
64057
65092
|
// populated after activation
|
|
64058
65093
|
identityKeypair: {
|
|
64059
|
-
publicKey:
|
|
64060
|
-
privateKey:
|
|
65094
|
+
publicKey: bytesToHex2(identity.publicKey),
|
|
65095
|
+
privateKey: bytesToHex2(identity.privateKey)
|
|
64061
65096
|
},
|
|
64062
65097
|
ephemeralKeypair: {
|
|
64063
|
-
publicKey:
|
|
64064
|
-
privateKey:
|
|
65098
|
+
publicKey: bytesToHex2(ephemeral.publicKey),
|
|
65099
|
+
privateKey: bytesToHex2(ephemeral.privateKey)
|
|
64065
65100
|
},
|
|
64066
65101
|
fingerprint: result.fingerprint,
|
|
64067
65102
|
messageHistory: []
|
|
@@ -64124,17 +65159,17 @@ var init_channel = __esm({
|
|
|
64124
65159
|
const ownerIdentityKey = conv.owner_identity_public_key || result.owner_identity_public_key;
|
|
64125
65160
|
const ownerEphemeralKey = conv.owner_ephemeral_public_key || result.owner_ephemeral_public_key || ownerIdentityKey;
|
|
64126
65161
|
const sharedSecret = performX3DH({
|
|
64127
|
-
myIdentityPrivate:
|
|
64128
|
-
myEphemeralPrivate:
|
|
64129
|
-
theirIdentityPublic:
|
|
64130
|
-
theirEphemeralPublic:
|
|
65162
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
65163
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
65164
|
+
theirIdentityPublic: hexToBytes2(ownerIdentityKey),
|
|
65165
|
+
theirEphemeralPublic: hexToBytes2(ownerEphemeralKey),
|
|
64131
65166
|
isInitiator: false
|
|
64132
65167
|
});
|
|
64133
65168
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
64134
|
-
publicKey:
|
|
64135
|
-
privateKey:
|
|
65169
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
65170
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
64136
65171
|
keyType: "ed25519"
|
|
64137
|
-
},
|
|
65172
|
+
}, hexToBytes2(ownerIdentityKey));
|
|
64138
65173
|
this._sessions.set(conv.conversation_id, {
|
|
64139
65174
|
ownerDeviceId: conv.owner_device_id,
|
|
64140
65175
|
ratchet,
|
|
@@ -65260,19 +66295,19 @@ ${messageText}`;
|
|
|
65260
66295
|
const identity = this._persisted.identityKeypair;
|
|
65261
66296
|
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65262
66297
|
const sharedSecret = performX3DH({
|
|
65263
|
-
myIdentityPrivate:
|
|
65264
|
-
myEphemeralPrivate:
|
|
65265
|
-
theirIdentityPublic:
|
|
65266
|
-
theirEphemeralPublic:
|
|
66298
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
66299
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
66300
|
+
theirIdentityPublic: hexToBytes2(event.owner_identity_public_key),
|
|
66301
|
+
theirEphemeralPublic: hexToBytes2(
|
|
65267
66302
|
event.owner_ephemeral_public_key ?? event.owner_identity_public_key
|
|
65268
66303
|
),
|
|
65269
66304
|
isInitiator: false
|
|
65270
66305
|
});
|
|
65271
66306
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
65272
|
-
publicKey:
|
|
65273
|
-
privateKey:
|
|
66307
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
66308
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
65274
66309
|
keyType: "ed25519"
|
|
65275
|
-
},
|
|
66310
|
+
}, hexToBytes2(event.owner_identity_public_key));
|
|
65276
66311
|
this._sessions.set(event.conversation_id, {
|
|
65277
66312
|
ownerDeviceId: event.owner_device_id,
|
|
65278
66313
|
ratchet,
|
|
@@ -65319,17 +66354,17 @@ ${messageText}`;
|
|
|
65319
66354
|
const identity = this._persisted.identityKeypair;
|
|
65320
66355
|
const ephemeral = this._persisted.ephemeralKeypair;
|
|
65321
66356
|
const sharedSecret = performX3DH({
|
|
65322
|
-
myIdentityPrivate:
|
|
65323
|
-
myEphemeralPrivate:
|
|
65324
|
-
theirIdentityPublic:
|
|
65325
|
-
theirEphemeralPublic:
|
|
66357
|
+
myIdentityPrivate: hexToBytes2(identity.privateKey),
|
|
66358
|
+
myEphemeralPrivate: hexToBytes2(ephemeral.privateKey),
|
|
66359
|
+
theirIdentityPublic: hexToBytes2(data.identity_public_key),
|
|
66360
|
+
theirEphemeralPublic: hexToBytes2(data.ephemeral_public_key),
|
|
65326
66361
|
isInitiator: false
|
|
65327
66362
|
});
|
|
65328
66363
|
const ratchet = DoubleRatchet.initReceiver(sharedSecret, {
|
|
65329
|
-
publicKey:
|
|
65330
|
-
privateKey:
|
|
66364
|
+
publicKey: hexToBytes2(identity.publicKey),
|
|
66365
|
+
privateKey: hexToBytes2(identity.privateKey),
|
|
65331
66366
|
keyType: "ed25519"
|
|
65332
|
-
},
|
|
66367
|
+
}, hexToBytes2(data.identity_public_key));
|
|
65333
66368
|
const existingSession = this._sessions.get(convId);
|
|
65334
66369
|
const existingPersisted = this._persisted.sessions[convId];
|
|
65335
66370
|
const ownerDeviceId = data.sender_device_id ?? existingSession?.ownerDeviceId ?? "";
|
|
@@ -65489,7 +66524,28 @@ ${messageText}`;
|
|
|
65489
66524
|
const mlsGroup = this._mlsGroups.get(resolvedRoomId);
|
|
65490
66525
|
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(",")}]`);
|
|
65491
66526
|
if (!mlsGroup?.isInitialized) {
|
|
65492
|
-
console.warn(`[SecureChannel] MLS group not loaded for room ${resolvedRoomId.slice(0, 8)}`);
|
|
66527
|
+
console.warn(`[SecureChannel] MLS group not loaded for room ${resolvedRoomId.slice(0, 8)}, requesting Welcome`);
|
|
66528
|
+
try {
|
|
66529
|
+
const { MLSGroupManager: MLS } = await init_dist().then(() => dist_exports);
|
|
66530
|
+
const mgr = new MLS();
|
|
66531
|
+
const kp = await mgr.generateKeyPackage(new TextEncoder().encode(this._deviceId));
|
|
66532
|
+
const kpBytes = MLS.serializeKeyPackage(kp.publicPackage);
|
|
66533
|
+
const kpHex = Buffer.from(kpBytes).toString("hex");
|
|
66534
|
+
await fetch(`${this.config.apiUrl}/api/v1/mls/key-packages`, {
|
|
66535
|
+
method: "POST",
|
|
66536
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66537
|
+
body: JSON.stringify({ key_package: kpHex, device_id: this._deviceId })
|
|
66538
|
+
});
|
|
66539
|
+
this._pendingMlsKpBundle = kp;
|
|
66540
|
+
await fetch(`${this.config.apiUrl}/api/v1/mls/groups/${groupId}/request-welcome`, {
|
|
66541
|
+
method: "POST",
|
|
66542
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66543
|
+
body: JSON.stringify({ device_id: this._deviceId })
|
|
66544
|
+
});
|
|
66545
|
+
console.log(`[SecureChannel] Welcome requested for room ${resolvedRoomId.slice(0, 8)} group ${groupId?.slice(0, 8)}`);
|
|
66546
|
+
} catch (reqErr) {
|
|
66547
|
+
console.warn(`[SecureChannel] Welcome request failed for room ${resolvedRoomId.slice(0, 8)}:`, reqErr);
|
|
66548
|
+
}
|
|
65493
66549
|
return;
|
|
65494
66550
|
}
|
|
65495
66551
|
try {
|
|
@@ -65518,6 +66574,12 @@ ${messageText}`;
|
|
|
65518
66574
|
await this._persistState();
|
|
65519
66575
|
return;
|
|
65520
66576
|
}
|
|
66577
|
+
if (CATCHUP_MESSAGE_TYPES.has(messageType)) {
|
|
66578
|
+
if (messageType === "history_catchup_request") {
|
|
66579
|
+
await this._handleHistoryCatchupRequest(resolvedRoomId, messageText, data.message_id);
|
|
66580
|
+
}
|
|
66581
|
+
return;
|
|
66582
|
+
}
|
|
65521
66583
|
if (!ROOM_AGENT_TYPES.has(messageType)) {
|
|
65522
66584
|
return;
|
|
65523
66585
|
}
|
|
@@ -65564,6 +66626,55 @@ ${messageText}`;
|
|
|
65564
66626
|
console.error(`[SecureChannel] MLS room decrypt failed for ${resolvedRoomId.slice(0, 8)}:`, err);
|
|
65565
66627
|
}
|
|
65566
66628
|
}
|
|
66629
|
+
/**
|
|
66630
|
+
* Handle a history catch-up request from a device that just rejoined a room.
|
|
66631
|
+
* Only the elected agent (smallest device_id among agents) responds.
|
|
66632
|
+
*/
|
|
66633
|
+
async _handleHistoryCatchupRequest(roomId, requestText, messageId) {
|
|
66634
|
+
let request;
|
|
66635
|
+
try {
|
|
66636
|
+
request = JSON.parse(requestText);
|
|
66637
|
+
} catch {
|
|
66638
|
+
return;
|
|
66639
|
+
}
|
|
66640
|
+
const roomMembers = this._persisted?.rooms?.[roomId]?.members ?? [];
|
|
66641
|
+
const agentDeviceIds = roomMembers.filter((m2) => m2.entityType !== "owner" && m2.entityType !== "human").map((m2) => m2.deviceId).sort();
|
|
66642
|
+
const isElected = agentDeviceIds.length > 0 && agentDeviceIds[0] === this._deviceId;
|
|
66643
|
+
if (!isElected && !request.retry) {
|
|
66644
|
+
console.log(
|
|
66645
|
+
`[SecureChannel] History catchup: not elected (elected=${agentDeviceIds[0]?.slice(0, 8)}), ignoring`
|
|
66646
|
+
);
|
|
66647
|
+
return;
|
|
66648
|
+
}
|
|
66649
|
+
const history = this.getRoomHistory(roomId, 100);
|
|
66650
|
+
let filtered = history;
|
|
66651
|
+
if (request.since_ts) {
|
|
66652
|
+
const sinceTime = new Date(request.since_ts).getTime();
|
|
66653
|
+
filtered = history.filter((e) => new Date(e.ts).getTime() > sinceTime);
|
|
66654
|
+
}
|
|
66655
|
+
console.log(
|
|
66656
|
+
`[SecureChannel] History catchup for room ${roomId.slice(0, 8)}: ${filtered.length} messages since ${request.since_ts || "beginning"} (total history: ${history.length})`
|
|
66657
|
+
);
|
|
66658
|
+
const responsePayload = JSON.stringify({
|
|
66659
|
+
type: "history_catchup_response",
|
|
66660
|
+
target_device_id: request.requesting_device_id,
|
|
66661
|
+
messages: filtered.map((e) => ({
|
|
66662
|
+
sender: e.sender,
|
|
66663
|
+
sender_name: e.sender === "agent" ? this.config.agentName ?? "Agent" : "Owner",
|
|
66664
|
+
text: e.text,
|
|
66665
|
+
ts: e.ts
|
|
66666
|
+
})),
|
|
66667
|
+
no_history: filtered.length === 0
|
|
66668
|
+
});
|
|
66669
|
+
try {
|
|
66670
|
+
await this.sendToRoom(roomId, responsePayload, { messageType: "history_catchup_response" });
|
|
66671
|
+
console.log(
|
|
66672
|
+
`[SecureChannel] Sent history catchup response: ${filtered.length} messages to ${request.requesting_device_id?.slice(0, 8)}`
|
|
66673
|
+
);
|
|
66674
|
+
} catch (sendErr) {
|
|
66675
|
+
console.warn(`[SecureChannel] Failed to send history catchup response:`, sendErr);
|
|
66676
|
+
}
|
|
66677
|
+
}
|
|
65567
66678
|
async _handleMlsCommit(data) {
|
|
65568
66679
|
const groupId = data.group_id;
|
|
65569
66680
|
for (const [roomId, room] of Object.entries(this._persisted?.rooms ?? {})) {
|
|
@@ -65590,7 +66701,7 @@ ${messageText}`;
|
|
|
65590
66701
|
try {
|
|
65591
66702
|
const welcomeBytes = new Uint8Array(Buffer.from(data.payload, "hex"));
|
|
65592
66703
|
const mgr = new MLSGroupManager();
|
|
65593
|
-
const kp = this._mlsKeyPackage ?? await (async () => {
|
|
66704
|
+
const kp = this._pendingMlsKpBundle ?? this._mlsKeyPackage ?? await (async () => {
|
|
65594
66705
|
const identity = new TextEncoder().encode(this._deviceId);
|
|
65595
66706
|
return mgr.generateKeyPackage(identity);
|
|
65596
66707
|
})();
|
|
@@ -65607,11 +66718,15 @@ ${messageText}`;
|
|
|
65607
66718
|
console.log(`[SecureChannel] Joined 1:1 MLS group for conv ${conversationId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
|
|
65608
66719
|
return;
|
|
65609
66720
|
}
|
|
66721
|
+
const welcomeRoomId = data.room_id;
|
|
65610
66722
|
for (const [roomId, room] of Object.entries(this._persisted?.rooms ?? {})) {
|
|
65611
|
-
if (room.mlsGroupId === groupId) {
|
|
66723
|
+
if (room.mlsGroupId === groupId || roomId === welcomeRoomId) {
|
|
66724
|
+
room.mlsGroupId = groupId;
|
|
65612
66725
|
this._mlsGroups.set(roomId, mgr);
|
|
65613
66726
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mgr.exportState()));
|
|
66727
|
+
await this._persistState();
|
|
65614
66728
|
console.log(`[SecureChannel] Joined MLS group for room ${roomId.slice(0, 8)} via Welcome (epoch=${mgr.epoch})`);
|
|
66729
|
+
this._pendingMlsKpBundle = void 0;
|
|
65615
66730
|
return;
|
|
65616
66731
|
}
|
|
65617
66732
|
}
|
|
@@ -65774,6 +66889,71 @@ ${messageText}`;
|
|
|
65774
66889
|
console.warn("[SecureChannel] Delivery ack failed:", ackErr);
|
|
65775
66890
|
}
|
|
65776
66891
|
}
|
|
66892
|
+
for (const [roomId, mlsGroup] of this._mlsGroups) {
|
|
66893
|
+
if (!mlsGroup?.isInitialized) continue;
|
|
66894
|
+
if (roomId.includes(":")) continue;
|
|
66895
|
+
const roomState = this._persisted?.rooms?.[roomId];
|
|
66896
|
+
if (!roomState?.mlsGroupId) continue;
|
|
66897
|
+
try {
|
|
66898
|
+
const pendingRes = await fetch(
|
|
66899
|
+
`${this.config.apiUrl}/api/v1/mls/groups/${roomState.mlsGroupId}/pending-welcomes`,
|
|
66900
|
+
{ headers: { Authorization: `Bearer ${this._deviceJwt}` } }
|
|
66901
|
+
);
|
|
66902
|
+
if (!pendingRes.ok) continue;
|
|
66903
|
+
const pending = await pendingRes.json();
|
|
66904
|
+
if (pending.length === 0) continue;
|
|
66905
|
+
console.log(`[SecureChannel] ${pending.length} pending Welcome requests for room ${roomId.slice(0, 8)}`);
|
|
66906
|
+
for (const req of pending) {
|
|
66907
|
+
try {
|
|
66908
|
+
const kpRes = await fetch(
|
|
66909
|
+
`${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
|
|
66910
|
+
{ headers: { Authorization: `Bearer ${this._deviceJwt}` } }
|
|
66911
|
+
);
|
|
66912
|
+
if (!kpRes.ok) continue;
|
|
66913
|
+
const kpData = await kpRes.json();
|
|
66914
|
+
const kpHex = kpData[req.requesting_device_id];
|
|
66915
|
+
if (!kpHex) continue;
|
|
66916
|
+
const kpBytes = new Uint8Array(Buffer.from(kpHex, "hex"));
|
|
66917
|
+
const memberKp = MLSGroupManager.deserializeKeyPackage(kpBytes);
|
|
66918
|
+
const { commit, welcome } = await mlsGroup.addMembers([memberKp]);
|
|
66919
|
+
if (this._ws) {
|
|
66920
|
+
this._ws.send(JSON.stringify({
|
|
66921
|
+
event: "mls_commit",
|
|
66922
|
+
data: {
|
|
66923
|
+
group_id: roomState.mlsGroupId,
|
|
66924
|
+
epoch: Number(mlsGroup.epoch),
|
|
66925
|
+
payload: Buffer.from(commit).toString("hex")
|
|
66926
|
+
}
|
|
66927
|
+
}));
|
|
66928
|
+
}
|
|
66929
|
+
if (welcome && this._ws) {
|
|
66930
|
+
this._ws.send(JSON.stringify({
|
|
66931
|
+
event: "mls_welcome",
|
|
66932
|
+
data: {
|
|
66933
|
+
target_device_id: req.requesting_device_id,
|
|
66934
|
+
group_id: roomState.mlsGroupId,
|
|
66935
|
+
room_id: roomId,
|
|
66936
|
+
payload: Buffer.from(welcome).toString("hex")
|
|
66937
|
+
}
|
|
66938
|
+
}));
|
|
66939
|
+
}
|
|
66940
|
+
await fetch(
|
|
66941
|
+
`${this.config.apiUrl}/api/v1/mls/groups/${roomState.mlsGroupId}/fulfill-welcome`,
|
|
66942
|
+
{
|
|
66943
|
+
method: "POST",
|
|
66944
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
66945
|
+
body: JSON.stringify({ request_id: req.id })
|
|
66946
|
+
}
|
|
66947
|
+
);
|
|
66948
|
+
await saveMlsState(this.config.dataDir, roomState.mlsGroupId, JSON.stringify(mlsGroup.exportState()));
|
|
66949
|
+
console.log(`[SecureChannel] Fulfilled Welcome for ${req.requesting_device_id.slice(0, 8)} in room ${roomId.slice(0, 8)}`);
|
|
66950
|
+
} catch (fulfillErr) {
|
|
66951
|
+
console.warn(`[SecureChannel] Welcome fulfill failed for ${req.requesting_device_id.slice(0, 8)}:`, fulfillErr);
|
|
66952
|
+
}
|
|
66953
|
+
}
|
|
66954
|
+
} catch {
|
|
66955
|
+
}
|
|
66956
|
+
}
|
|
65777
66957
|
} catch (err) {
|
|
65778
66958
|
console.warn("[SecureChannel] Delivery pull error:", err);
|
|
65779
66959
|
} finally {
|