@anuma/sdk 4.2.0 → 4.2.1
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/expo/{chunk-VBO6KSNQ.mjs → chunk-3CDSIN22.mjs} +304 -49
- package/dist/expo/index.cjs +307 -49
- package/dist/expo/index.d.mts +92 -7
- package/dist/expo/index.d.ts +92 -7
- package/dist/expo/index.mjs +7 -1
- package/dist/expo/{recall-OCQOA7M3.mjs → recall-NARBDQAK.mjs} +1 -1
- package/dist/index.cjs +31 -17
- package/dist/index.mjs +31 -17
- package/dist/react/{chunk-BS7C4CUW.mjs → chunk-CUJDSH55.mjs} +304 -49
- package/dist/react/index.cjs +307 -49
- package/dist/react/index.d.mts +86 -7
- package/dist/react/index.d.ts +86 -7
- package/dist/react/index.mjs +7 -1
- package/dist/react/{recall-WXCZHXHZ.mjs → recall-FPPCKYYH.mjs} +1 -1
- package/dist/server/{chunk-WADHFDMA.mjs → chunk-UQDYBQVF.mjs} +304 -49
- package/dist/server/index.cjs +307 -49
- package/dist/server/index.d.mts +85 -6
- package/dist/server/index.d.ts +85 -6
- package/dist/server/index.mjs +7 -1
- package/dist/server/{recall-QTVT7HCZ.mjs → recall-ZHEPQNEU.mjs} +1 -1
- package/package.json +1 -1
|
@@ -13,8 +13,21 @@ import { v7 as uuidv72 } from "uuid";
|
|
|
13
13
|
|
|
14
14
|
// src/react/useEncryption.ts
|
|
15
15
|
var SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
|
|
16
|
+
var EncryptionKeyMissingError = class extends Error {
|
|
17
|
+
constructor(address, version) {
|
|
18
|
+
super(
|
|
19
|
+
`Encryption key (${version}) not found for ${address}. Please sign a message to generate your encryption key.`
|
|
20
|
+
);
|
|
21
|
+
this.name = "EncryptionKeyMissingError";
|
|
22
|
+
this.address = address;
|
|
23
|
+
this.version = version;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
16
26
|
var encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
17
27
|
var pendingKeyRequests = /* @__PURE__ */ new Map();
|
|
28
|
+
var pendingCandidateDerives = /* @__PURE__ */ new Map();
|
|
29
|
+
var refreshCandidatesByAddress = /* @__PURE__ */ new Map();
|
|
30
|
+
var divergentDeriveAddresses = /* @__PURE__ */ new Set();
|
|
18
31
|
var sessionEpoch = 0;
|
|
19
32
|
var cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
20
33
|
var keyAvailableCallbacks = /* @__PURE__ */ new Map();
|
|
@@ -57,14 +70,11 @@ function notifyKeyAvailable(address) {
|
|
|
57
70
|
}
|
|
58
71
|
}
|
|
59
72
|
var keyPairStore = /* @__PURE__ */ new Map();
|
|
60
|
-
function getStoredKey(address) {
|
|
61
|
-
const keys = encryptionKeyStore.get(address);
|
|
62
|
-
return keys?.current ?? null;
|
|
63
|
-
}
|
|
64
73
|
function getStoredKeyByVersion(address, version) {
|
|
65
74
|
const keys = encryptionKeyStore.get(address);
|
|
66
75
|
if (!keys) return null;
|
|
67
|
-
|
|
76
|
+
const value = version === "v2" ? keys.legacy : keys.current;
|
|
77
|
+
return value ?? null;
|
|
68
78
|
}
|
|
69
79
|
function setStoredKey(address, keys) {
|
|
70
80
|
encryptionKeyStore.set(address, keys);
|
|
@@ -73,6 +83,8 @@ function clearEncryptionKey(address) {
|
|
|
73
83
|
encryptionKeyStore.delete(address);
|
|
74
84
|
cryptoKeyCache.delete(`${address}:v2`);
|
|
75
85
|
cryptoKeyCache.delete(`${address}:v3`);
|
|
86
|
+
refreshCandidatesByAddress.delete(address);
|
|
87
|
+
divergentDeriveAddresses.delete(address);
|
|
76
88
|
}
|
|
77
89
|
function clearAllEncryptionState() {
|
|
78
90
|
sessionEpoch += 1;
|
|
@@ -80,6 +92,9 @@ function clearAllEncryptionState() {
|
|
|
80
92
|
cryptoKeyCache.clear();
|
|
81
93
|
keyAvailableCallbacks.clear();
|
|
82
94
|
pendingKeyRequests.clear();
|
|
95
|
+
pendingCandidateDerives.clear();
|
|
96
|
+
refreshCandidatesByAddress.clear();
|
|
97
|
+
divergentDeriveAddresses.clear();
|
|
83
98
|
clearAllKeyPairs();
|
|
84
99
|
for (const cb of clearAllEncryptionStateCallbacks) {
|
|
85
100
|
try {
|
|
@@ -265,9 +280,7 @@ async function getEncryptionKey(address, version = "v3") {
|
|
|
265
280
|
}
|
|
266
281
|
const keyHex = getStoredKeyByVersion(address, version);
|
|
267
282
|
if (!keyHex) {
|
|
268
|
-
throw new
|
|
269
|
-
"Encryption key not found. Please sign a message to generate your encryption key."
|
|
270
|
-
);
|
|
283
|
+
throw new EncryptionKeyMissingError(address, version);
|
|
271
284
|
}
|
|
272
285
|
const keyBytes = hexToBytes(keyHex);
|
|
273
286
|
const cryptoKey = await crypto.subtle.importKey(
|
|
@@ -293,8 +306,43 @@ async function decryptData(encryptedHex, address, version = "v3") {
|
|
|
293
306
|
const key = await getEncryptionKey(address, version);
|
|
294
307
|
return decryptDataWithKey(encryptedHex, key);
|
|
295
308
|
}
|
|
296
|
-
function hasEncryptionKey(address) {
|
|
297
|
-
return
|
|
309
|
+
function hasEncryptionKey(address, version) {
|
|
310
|
+
return getStoredKeyByVersion(address, version ?? "v3") !== null;
|
|
311
|
+
}
|
|
312
|
+
function seedEncryptionKeys(address, keys) {
|
|
313
|
+
if (!isValidWalletAddress(address)) {
|
|
314
|
+
throw new Error(
|
|
315
|
+
`Invalid wallet address: ${address}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
if (!keys.legacy && !keys.current) {
|
|
319
|
+
throw new Error("seedEncryptionKeys: at least one of legacy or current is required");
|
|
320
|
+
}
|
|
321
|
+
if (keys.legacy !== void 0) {
|
|
322
|
+
assertAes256KeyHex("legacy", keys.legacy);
|
|
323
|
+
}
|
|
324
|
+
if (keys.current !== void 0) {
|
|
325
|
+
assertAes256KeyHex("current", keys.current);
|
|
326
|
+
}
|
|
327
|
+
const existing = encryptionKeyStore.get(address);
|
|
328
|
+
const next = {
|
|
329
|
+
legacy: keys.legacy ?? existing?.legacy,
|
|
330
|
+
current: keys.current ?? existing?.current
|
|
331
|
+
};
|
|
332
|
+
setStoredKey(address, next);
|
|
333
|
+
if (keys.legacy !== void 0) cryptoKeyCache.delete(`${address}:v2`);
|
|
334
|
+
if (keys.current !== void 0) cryptoKeyCache.delete(`${address}:v3`);
|
|
335
|
+
refreshCandidatesByAddress.delete(address);
|
|
336
|
+
divergentDeriveAddresses.delete(address);
|
|
337
|
+
notifyKeyAvailable(address);
|
|
338
|
+
}
|
|
339
|
+
var AES_256_KEY_HEX = /^[0-9a-fA-F]{64}$/;
|
|
340
|
+
function assertAes256KeyHex(field, value) {
|
|
341
|
+
if (!AES_256_KEY_HEX.test(value)) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`seedEncryptionKeys: ${field} must be 64 hex characters (32-byte AES key), got length ${value.length}`
|
|
344
|
+
);
|
|
345
|
+
}
|
|
298
346
|
}
|
|
299
347
|
async function encryptBytesWithKey(plaintext, key) {
|
|
300
348
|
const plaintextBytes = typeof plaintext === "string" ? SHARED_TEXT_ENCODER.encode(plaintext) : plaintext;
|
|
@@ -330,20 +378,23 @@ async function decryptDataWithKey(encryptedHex, key) {
|
|
|
330
378
|
);
|
|
331
379
|
return SHARED_TEXT_DECODER.decode(decryptedData);
|
|
332
380
|
}
|
|
333
|
-
async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSigner) {
|
|
381
|
+
async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSigner, options) {
|
|
334
382
|
if (!isValidWalletAddress(walletAddress)) {
|
|
335
383
|
throw new Error(
|
|
336
384
|
`Invalid wallet address: ${walletAddress}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
337
385
|
);
|
|
338
386
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
return;
|
|
387
|
+
if (!options?.force && getStoredKeyByVersion(walletAddress, "v3") && getStoredKeyByVersion(walletAddress, "v2")) {
|
|
388
|
+
return true;
|
|
342
389
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
390
|
+
if (!options?.force && divergentDeriveAddresses.has(walletAddress)) {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
if (!options?.force) {
|
|
394
|
+
const pending = pendingKeyRequests.get(walletAddress);
|
|
395
|
+
if (pending) {
|
|
396
|
+
return pending;
|
|
397
|
+
}
|
|
347
398
|
}
|
|
348
399
|
const startEpoch = sessionEpoch;
|
|
349
400
|
const promise = (async () => {
|
|
@@ -371,20 +422,143 @@ async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSi
|
|
|
371
422
|
deriveKeyFromSignatureV3(signature)
|
|
372
423
|
]);
|
|
373
424
|
if (sessionEpoch !== startEpoch) {
|
|
374
|
-
return;
|
|
425
|
+
return false;
|
|
375
426
|
}
|
|
376
|
-
|
|
427
|
+
const existing = encryptionKeyStore.get(walletAddress);
|
|
428
|
+
if (!options?.force && existing && (existing.legacy || existing.current)) {
|
|
429
|
+
const matchesCurrent = Boolean(existing.current && existing.current === currentKey);
|
|
430
|
+
const matchesLegacy = Boolean(existing.legacy && existing.legacy === legacyKey);
|
|
431
|
+
if (!matchesCurrent && !matchesLegacy) {
|
|
432
|
+
getLogger().warn(
|
|
433
|
+
"requestEncryptionKey: derived keys do not match existing store; leaving unchanged"
|
|
434
|
+
);
|
|
435
|
+
divergentDeriveAddresses.add(walletAddress);
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
setStoredKey(walletAddress, {
|
|
439
|
+
legacy: existing.legacy ?? legacyKey,
|
|
440
|
+
current: existing.current ?? currentKey
|
|
441
|
+
});
|
|
442
|
+
} else {
|
|
443
|
+
setStoredKey(walletAddress, { legacy: legacyKey, current: currentKey });
|
|
444
|
+
}
|
|
445
|
+
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
446
|
+
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
447
|
+
refreshCandidatesByAddress.delete(walletAddress);
|
|
448
|
+
divergentDeriveAddresses.delete(walletAddress);
|
|
377
449
|
notifyKeyAvailable(walletAddress);
|
|
450
|
+
return true;
|
|
378
451
|
})();
|
|
379
452
|
pendingKeyRequests.set(walletAddress, promise);
|
|
380
453
|
try {
|
|
381
|
-
await promise;
|
|
454
|
+
return await promise;
|
|
382
455
|
} finally {
|
|
383
456
|
if (pendingKeyRequests.get(walletAddress) === promise) {
|
|
384
457
|
pendingKeyRequests.delete(walletAddress);
|
|
385
458
|
}
|
|
386
459
|
}
|
|
387
460
|
}
|
|
461
|
+
async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, signMessage, embeddedWalletSigner) {
|
|
462
|
+
if (!isValidWalletAddress(walletAddress)) {
|
|
463
|
+
throw new Error(
|
|
464
|
+
`Invalid wallet address: ${walletAddress}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
const parsed = parsePrefixedCiphertext(probeCiphertext);
|
|
468
|
+
if (!parsed) {
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
472
|
+
if (cached) {
|
|
473
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
474
|
+
}
|
|
475
|
+
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
476
|
+
if (!derivePromise) {
|
|
477
|
+
derivePromise = (async () => {
|
|
478
|
+
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
479
|
+
if (candidates2) {
|
|
480
|
+
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
481
|
+
}
|
|
482
|
+
return candidates2;
|
|
483
|
+
})().finally(() => {
|
|
484
|
+
if (pendingCandidateDerives.get(walletAddress) === derivePromise) {
|
|
485
|
+
pendingCandidateDerives.delete(walletAddress);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
489
|
+
}
|
|
490
|
+
const candidates = await derivePromise;
|
|
491
|
+
if (!candidates) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
495
|
+
}
|
|
496
|
+
function parsePrefixedCiphertext(probeCiphertext) {
|
|
497
|
+
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
498
|
+
if (!version) return null;
|
|
499
|
+
const encryptedData = probeCiphertext.slice(
|
|
500
|
+
version === "v3" ? "enc:v3:".length : "enc:v2:".length
|
|
501
|
+
);
|
|
502
|
+
if (encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(encryptedData)) {
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
return { version, encryptedData };
|
|
506
|
+
}
|
|
507
|
+
async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
508
|
+
const startEpoch = sessionEpoch;
|
|
509
|
+
const signOptions = { showWalletUIs: false };
|
|
510
|
+
let signature;
|
|
511
|
+
try {
|
|
512
|
+
if (embeddedWalletSigner) {
|
|
513
|
+
signature = await embeddedWalletSigner(SIGN_MESSAGE, signOptions);
|
|
514
|
+
} else {
|
|
515
|
+
signature = await signMessage(SIGN_MESSAGE, signOptions);
|
|
516
|
+
}
|
|
517
|
+
} catch (error) {
|
|
518
|
+
if (embeddedWalletSigner && error instanceof Error) {
|
|
519
|
+
getLogger().warn(
|
|
520
|
+
"Embedded wallet signing failed during key refresh, falling back to standard signMessage:",
|
|
521
|
+
error.message
|
|
522
|
+
);
|
|
523
|
+
signature = await signMessage(SIGN_MESSAGE, signOptions);
|
|
524
|
+
} else {
|
|
525
|
+
throw error;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
const [legacyKey, currentKey] = await Promise.all([
|
|
529
|
+
deriveKeyFromSignature(signature),
|
|
530
|
+
deriveKeyFromSignatureV3(signature)
|
|
531
|
+
]);
|
|
532
|
+
if (sessionEpoch !== startEpoch) {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
return { legacy: legacyKey, current: currentKey };
|
|
536
|
+
}
|
|
537
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
538
|
+
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
539
|
+
const keyBytes = hexToBytes(candidateHex);
|
|
540
|
+
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
541
|
+
"raw",
|
|
542
|
+
keyBytes.buffer,
|
|
543
|
+
{ name: "AES-GCM" },
|
|
544
|
+
false,
|
|
545
|
+
["encrypt", "decrypt"]
|
|
546
|
+
);
|
|
547
|
+
try {
|
|
548
|
+
await decryptDataWithKey(parsed.encryptedData, candidateCryptoKey);
|
|
549
|
+
} catch {
|
|
550
|
+
getLogger().warn(
|
|
551
|
+
"refreshEncryptionKeyIfMatches: candidate keys failed to decrypt probe; leaving store unchanged"
|
|
552
|
+
);
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
556
|
+
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
557
|
+
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
558
|
+
divergentDeriveAddresses.delete(walletAddress);
|
|
559
|
+
notifyKeyAvailable(walletAddress);
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
388
562
|
var KEYPAIR_STORAGE_PREFIX = "ecdh_keypair_";
|
|
389
563
|
async function persistKeyPair(address, startEpoch) {
|
|
390
564
|
if (typeof window === "undefined") {
|
|
@@ -664,20 +838,29 @@ async function encryptField(value, address, signMessage, embeddedWalletSigner, s
|
|
|
664
838
|
const encrypted = await encryptData(value, address);
|
|
665
839
|
return `${ENCRYPTION_PREFIX}${encrypted}`;
|
|
666
840
|
}
|
|
667
|
-
async function
|
|
668
|
-
if (!value) return value;
|
|
841
|
+
async function decryptFieldDetailed(value, address) {
|
|
842
|
+
if (!value) return { status: "plaintext", value };
|
|
669
843
|
const detected = detectEncryptionVersion(value);
|
|
670
|
-
if (!detected) return value;
|
|
844
|
+
if (!detected) return { status: "plaintext", value };
|
|
671
845
|
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
672
|
-
return value;
|
|
846
|
+
return { status: "invalid_payload", value, version: detected.version };
|
|
673
847
|
}
|
|
674
848
|
try {
|
|
675
|
-
|
|
849
|
+
const plaintext = await decryptData(detected.encryptedData, address, detected.version);
|
|
850
|
+
return { status: "ok", value: plaintext, version: detected.version };
|
|
676
851
|
} catch (error) {
|
|
677
|
-
|
|
678
|
-
|
|
852
|
+
if (error instanceof EncryptionKeyMissingError) {
|
|
853
|
+
getLogger().warn("Failed to decrypt field (key missing for version):", error.message);
|
|
854
|
+
return { status: "key_missing", value, version: detected.version };
|
|
855
|
+
}
|
|
856
|
+
getLogger().warn("Failed to decrypt field (auth mismatch or crypto error):", error);
|
|
857
|
+
return { status: "auth_mismatch", value, version: detected.version };
|
|
679
858
|
}
|
|
680
859
|
}
|
|
860
|
+
async function decryptField(value, address) {
|
|
861
|
+
const result = await decryptFieldDetailed(value, address);
|
|
862
|
+
return result.value;
|
|
863
|
+
}
|
|
681
864
|
async function encryptJsonField(value, address, signMessage, embeddedWalletSigner, skipKeyRequest) {
|
|
682
865
|
if (!value) return void 0;
|
|
683
866
|
const jsonString = JSON.stringify(value);
|
|
@@ -777,20 +960,40 @@ async function encryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
777
960
|
throw error;
|
|
778
961
|
}
|
|
779
962
|
}
|
|
780
|
-
async function
|
|
781
|
-
if (value === void 0) return void 0;
|
|
782
|
-
if (value === null) return value;
|
|
963
|
+
async function decryptMaybeJsonFieldDetailed(value, address) {
|
|
964
|
+
if (value === void 0) return { value: void 0, status: "plaintext" };
|
|
965
|
+
if (value === null) return { value, status: "plaintext" };
|
|
783
966
|
if (typeof value === "string") {
|
|
784
967
|
if (isEncrypted(value)) {
|
|
785
|
-
|
|
968
|
+
const detailed = await decryptFieldDetailed(value, address);
|
|
969
|
+
if (detailed.status !== "ok") {
|
|
970
|
+
return { value: void 0, status: detailed.status, probe: value };
|
|
971
|
+
}
|
|
972
|
+
try {
|
|
973
|
+
return { value: JSON.parse(detailed.value), status: "ok" };
|
|
974
|
+
} catch (error) {
|
|
975
|
+
getLogger().warn("Failed to parse decrypted JSON field:", error);
|
|
976
|
+
return { value: void 0, status: "invalid_payload", probe: value };
|
|
977
|
+
}
|
|
786
978
|
}
|
|
787
979
|
try {
|
|
788
|
-
return JSON.parse(value);
|
|
980
|
+
return { value: JSON.parse(value), status: "plaintext" };
|
|
789
981
|
} catch {
|
|
790
|
-
return void 0;
|
|
982
|
+
return { value: void 0, status: "plaintext" };
|
|
791
983
|
}
|
|
792
984
|
}
|
|
793
|
-
return value;
|
|
985
|
+
return { value, status: "plaintext" };
|
|
986
|
+
}
|
|
987
|
+
function worseDecryptStatus(a, b) {
|
|
988
|
+
if (b === "ok" || b === "plaintext") return a;
|
|
989
|
+
if (!a || a === "ok" || a === "plaintext") return b;
|
|
990
|
+
const rank = (s) => {
|
|
991
|
+
if (s === "auth_mismatch") return 3;
|
|
992
|
+
if (s === "key_missing") return 2;
|
|
993
|
+
if (s === "invalid_payload") return 1;
|
|
994
|
+
return 0;
|
|
995
|
+
};
|
|
996
|
+
return rank(b) >= rank(a) ? b : a;
|
|
794
997
|
}
|
|
795
998
|
async function decryptMessageFields(message, address, signMessage, embeddedWalletSigner) {
|
|
796
999
|
if (!address) {
|
|
@@ -803,33 +1006,82 @@ async function decryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
803
1006
|
getLogger().warn("Failed to request encryption key for decryption:", error);
|
|
804
1007
|
}
|
|
805
1008
|
}
|
|
806
|
-
|
|
807
|
-
const
|
|
808
|
-
|
|
1009
|
+
let assembled = await assembleDecryptedMessage(message, address);
|
|
1010
|
+
const needsRefresh = assembled.decryptionStatus === "auth_mismatch" || assembled.decryptionStatus === "key_missing";
|
|
1011
|
+
if (needsRefresh && signMessage && assembled.refreshProbe) {
|
|
1012
|
+
try {
|
|
1013
|
+
const refreshed = await refreshEncryptionKeyIfMatches(
|
|
1014
|
+
address,
|
|
1015
|
+
assembled.refreshProbe,
|
|
1016
|
+
signMessage,
|
|
1017
|
+
embeddedWalletSigner
|
|
1018
|
+
);
|
|
1019
|
+
if (refreshed) {
|
|
1020
|
+
assembled = await assembleDecryptedMessage(message, address);
|
|
1021
|
+
}
|
|
1022
|
+
} catch (error) {
|
|
1023
|
+
getLogger().warn("Failed to refresh encryption key after decrypt failure:", error);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const { refreshProbe: _probe, ...result } = assembled;
|
|
1027
|
+
return result;
|
|
1028
|
+
}
|
|
1029
|
+
async function assembleDecryptedMessage(message, address) {
|
|
1030
|
+
const contentResult = await decryptFieldDetailed(message.content, address);
|
|
1031
|
+
const thinkingResult = message.thinking ? await decryptFieldDetailed(message.thinking, address) : null;
|
|
1032
|
+
const vectorResult = await decryptMaybeJsonFieldDetailed(
|
|
809
1033
|
message.vector,
|
|
810
1034
|
address
|
|
811
1035
|
);
|
|
812
|
-
const
|
|
1036
|
+
const chunksResult = await decryptMaybeJsonFieldDetailed(
|
|
813
1037
|
message.chunks,
|
|
814
1038
|
address
|
|
815
1039
|
);
|
|
816
|
-
const
|
|
1040
|
+
const sourcesResult = await decryptMaybeJsonFieldDetailed(
|
|
817
1041
|
message.sources,
|
|
818
1042
|
address
|
|
819
1043
|
);
|
|
820
|
-
const
|
|
1044
|
+
const thoughtProcessResult = await decryptMaybeJsonFieldDetailed(
|
|
821
1045
|
message.thoughtProcess,
|
|
822
1046
|
address
|
|
823
1047
|
);
|
|
824
|
-
|
|
1048
|
+
let decryptionStatus;
|
|
1049
|
+
let refreshProbe;
|
|
1050
|
+
const consider = (status, probe) => {
|
|
1051
|
+
decryptionStatus = worseDecryptStatus(decryptionStatus, status);
|
|
1052
|
+
if (!refreshProbe && probe && (status === "auth_mismatch" || status === "key_missing")) {
|
|
1053
|
+
refreshProbe = probe;
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
consider(contentResult.status, isEncrypted(message.content) ? message.content : void 0);
|
|
1057
|
+
if (thinkingResult && message.thinking && typeof message.thinking === "string") {
|
|
1058
|
+
consider(thinkingResult.status, isEncrypted(message.thinking) ? message.thinking : void 0);
|
|
1059
|
+
}
|
|
1060
|
+
if (vectorResult.probe) consider(vectorResult.status, vectorResult.probe);
|
|
1061
|
+
if (chunksResult.probe) consider(chunksResult.status, chunksResult.probe);
|
|
1062
|
+
if (sourcesResult.probe) consider(sourcesResult.status, sourcesResult.probe);
|
|
1063
|
+
if (thoughtProcessResult.probe) {
|
|
1064
|
+
consider(thoughtProcessResult.status, thoughtProcessResult.probe);
|
|
1065
|
+
}
|
|
1066
|
+
const statusForConsumer = decryptionStatus === "ok" || decryptionStatus === "plaintext" || !decryptionStatus ? void 0 : decryptionStatus;
|
|
1067
|
+
const result = {
|
|
825
1068
|
...message,
|
|
826
|
-
content:
|
|
827
|
-
thinking:
|
|
828
|
-
vector:
|
|
829
|
-
chunks:
|
|
830
|
-
sources:
|
|
831
|
-
thoughtProcess:
|
|
1069
|
+
content: contentResult.value,
|
|
1070
|
+
thinking: thinkingResult ? thinkingResult.value : message.thinking,
|
|
1071
|
+
vector: vectorResult.value,
|
|
1072
|
+
chunks: chunksResult.value,
|
|
1073
|
+
sources: sourcesResult.value,
|
|
1074
|
+
thoughtProcess: thoughtProcessResult.value
|
|
832
1075
|
};
|
|
1076
|
+
if (statusForConsumer) {
|
|
1077
|
+
result.decryptionStatus = statusForConsumer;
|
|
1078
|
+
} else {
|
|
1079
|
+
delete result.decryptionStatus;
|
|
1080
|
+
}
|
|
1081
|
+
if (refreshProbe) {
|
|
1082
|
+
result.refreshProbe = refreshProbe;
|
|
1083
|
+
}
|
|
1084
|
+
return result;
|
|
833
1085
|
}
|
|
834
1086
|
|
|
835
1087
|
// src/lib/db/chat/types.ts
|
|
@@ -6159,7 +6411,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
6159
6411
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
6160
6412
|
);
|
|
6161
6413
|
}
|
|
6162
|
-
const { recall: recall2 } = await import("./recall-
|
|
6414
|
+
const { recall: recall2 } = await import("./recall-NARBDQAK.mjs");
|
|
6163
6415
|
let recallDegraded = [];
|
|
6164
6416
|
const result = await recall2(
|
|
6165
6417
|
query,
|
|
@@ -7098,13 +7350,16 @@ function toChunkMemory(r) {
|
|
|
7098
7350
|
}
|
|
7099
7351
|
|
|
7100
7352
|
export {
|
|
7353
|
+
EncryptionKeyMissingError,
|
|
7101
7354
|
onClearAllEncryptionState,
|
|
7102
7355
|
onKeyAvailable,
|
|
7103
7356
|
clearEncryptionKey,
|
|
7104
7357
|
clearAllEncryptionState,
|
|
7105
7358
|
clearAllEncryptionKeys,
|
|
7106
7359
|
hasEncryptionKey,
|
|
7360
|
+
seedEncryptionKeys,
|
|
7107
7361
|
requestEncryptionKey,
|
|
7362
|
+
refreshEncryptionKeyIfMatches,
|
|
7108
7363
|
useEncryption,
|
|
7109
7364
|
cosineSimilarity,
|
|
7110
7365
|
isEncrypted,
|