@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
package/dist/react/index.cjs
CHANGED
|
@@ -276,14 +276,11 @@ function notifyKeyAvailable(address) {
|
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
|
-
function getStoredKey(address) {
|
|
280
|
-
const keys = encryptionKeyStore.get(address);
|
|
281
|
-
return keys?.current ?? null;
|
|
282
|
-
}
|
|
283
279
|
function getStoredKeyByVersion(address, version) {
|
|
284
280
|
const keys = encryptionKeyStore.get(address);
|
|
285
281
|
if (!keys) return null;
|
|
286
|
-
|
|
282
|
+
const value = version === "v2" ? keys.legacy : keys.current;
|
|
283
|
+
return value ?? null;
|
|
287
284
|
}
|
|
288
285
|
function setStoredKey(address, keys) {
|
|
289
286
|
encryptionKeyStore.set(address, keys);
|
|
@@ -292,6 +289,8 @@ function clearEncryptionKey(address) {
|
|
|
292
289
|
encryptionKeyStore.delete(address);
|
|
293
290
|
cryptoKeyCache.delete(`${address}:v2`);
|
|
294
291
|
cryptoKeyCache.delete(`${address}:v3`);
|
|
292
|
+
refreshCandidatesByAddress.delete(address);
|
|
293
|
+
divergentDeriveAddresses.delete(address);
|
|
295
294
|
}
|
|
296
295
|
function clearAllEncryptionState() {
|
|
297
296
|
sessionEpoch += 1;
|
|
@@ -299,6 +298,9 @@ function clearAllEncryptionState() {
|
|
|
299
298
|
cryptoKeyCache.clear();
|
|
300
299
|
keyAvailableCallbacks.clear();
|
|
301
300
|
pendingKeyRequests.clear();
|
|
301
|
+
pendingCandidateDerives.clear();
|
|
302
|
+
refreshCandidatesByAddress.clear();
|
|
303
|
+
divergentDeriveAddresses.clear();
|
|
302
304
|
clearAllKeyPairs();
|
|
303
305
|
for (const cb of clearAllEncryptionStateCallbacks) {
|
|
304
306
|
try {
|
|
@@ -482,9 +484,7 @@ async function getEncryptionKey(address, version = "v3") {
|
|
|
482
484
|
}
|
|
483
485
|
const keyHex = getStoredKeyByVersion(address, version);
|
|
484
486
|
if (!keyHex) {
|
|
485
|
-
throw new
|
|
486
|
-
"Encryption key not found. Please sign a message to generate your encryption key."
|
|
487
|
-
);
|
|
487
|
+
throw new EncryptionKeyMissingError(address, version);
|
|
488
488
|
}
|
|
489
489
|
const keyBytes = hexToBytes(keyHex);
|
|
490
490
|
const cryptoKey = await crypto.subtle.importKey(
|
|
@@ -548,8 +548,42 @@ async function decryptDataBytesFromBytes(encrypted, address, version = "v3") {
|
|
|
548
548
|
);
|
|
549
549
|
return new Uint8Array(decryptedData);
|
|
550
550
|
}
|
|
551
|
-
function hasEncryptionKey(address) {
|
|
552
|
-
return
|
|
551
|
+
function hasEncryptionKey(address, version) {
|
|
552
|
+
return getStoredKeyByVersion(address, version ?? "v3") !== null;
|
|
553
|
+
}
|
|
554
|
+
function seedEncryptionKeys(address, keys) {
|
|
555
|
+
if (!isValidWalletAddress(address)) {
|
|
556
|
+
throw new Error(
|
|
557
|
+
`Invalid wallet address: ${address}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
if (!keys.legacy && !keys.current) {
|
|
561
|
+
throw new Error("seedEncryptionKeys: at least one of legacy or current is required");
|
|
562
|
+
}
|
|
563
|
+
if (keys.legacy !== void 0) {
|
|
564
|
+
assertAes256KeyHex("legacy", keys.legacy);
|
|
565
|
+
}
|
|
566
|
+
if (keys.current !== void 0) {
|
|
567
|
+
assertAes256KeyHex("current", keys.current);
|
|
568
|
+
}
|
|
569
|
+
const existing = encryptionKeyStore.get(address);
|
|
570
|
+
const next = {
|
|
571
|
+
legacy: keys.legacy ?? existing?.legacy,
|
|
572
|
+
current: keys.current ?? existing?.current
|
|
573
|
+
};
|
|
574
|
+
setStoredKey(address, next);
|
|
575
|
+
if (keys.legacy !== void 0) cryptoKeyCache.delete(`${address}:v2`);
|
|
576
|
+
if (keys.current !== void 0) cryptoKeyCache.delete(`${address}:v3`);
|
|
577
|
+
refreshCandidatesByAddress.delete(address);
|
|
578
|
+
divergentDeriveAddresses.delete(address);
|
|
579
|
+
notifyKeyAvailable(address);
|
|
580
|
+
}
|
|
581
|
+
function assertAes256KeyHex(field10, value) {
|
|
582
|
+
if (!AES_256_KEY_HEX.test(value)) {
|
|
583
|
+
throw new Error(
|
|
584
|
+
`seedEncryptionKeys: ${field10} must be 64 hex characters (32-byte AES key), got length ${value.length}`
|
|
585
|
+
);
|
|
586
|
+
}
|
|
553
587
|
}
|
|
554
588
|
async function encryptBytesWithKey(plaintext, key) {
|
|
555
589
|
const plaintextBytes = typeof plaintext === "string" ? SHARED_TEXT_ENCODER.encode(plaintext) : plaintext;
|
|
@@ -598,20 +632,23 @@ async function decryptDataBatch(encryptedValues, address) {
|
|
|
598
632
|
const key = await getEncryptionKey(address);
|
|
599
633
|
return Promise.all(encryptedValues.map((value) => decryptDataWithKey(value, key)));
|
|
600
634
|
}
|
|
601
|
-
async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSigner) {
|
|
635
|
+
async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSigner, options) {
|
|
602
636
|
if (!isValidWalletAddress(walletAddress)) {
|
|
603
637
|
throw new Error(
|
|
604
638
|
`Invalid wallet address: ${walletAddress}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
605
639
|
);
|
|
606
640
|
}
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
return;
|
|
641
|
+
if (!options?.force && getStoredKeyByVersion(walletAddress, "v3") && getStoredKeyByVersion(walletAddress, "v2")) {
|
|
642
|
+
return true;
|
|
610
643
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
644
|
+
if (!options?.force && divergentDeriveAddresses.has(walletAddress)) {
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
if (!options?.force) {
|
|
648
|
+
const pending = pendingKeyRequests.get(walletAddress);
|
|
649
|
+
if (pending) {
|
|
650
|
+
return pending;
|
|
651
|
+
}
|
|
615
652
|
}
|
|
616
653
|
const startEpoch = sessionEpoch;
|
|
617
654
|
const promise = (async () => {
|
|
@@ -639,20 +676,143 @@ async function requestEncryptionKey(walletAddress, signMessage, embeddedWalletSi
|
|
|
639
676
|
deriveKeyFromSignatureV3(signature)
|
|
640
677
|
]);
|
|
641
678
|
if (sessionEpoch !== startEpoch) {
|
|
642
|
-
return;
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
const existing = encryptionKeyStore.get(walletAddress);
|
|
682
|
+
if (!options?.force && existing && (existing.legacy || existing.current)) {
|
|
683
|
+
const matchesCurrent = Boolean(existing.current && existing.current === currentKey);
|
|
684
|
+
const matchesLegacy = Boolean(existing.legacy && existing.legacy === legacyKey);
|
|
685
|
+
if (!matchesCurrent && !matchesLegacy) {
|
|
686
|
+
getLogger().warn(
|
|
687
|
+
"requestEncryptionKey: derived keys do not match existing store; leaving unchanged"
|
|
688
|
+
);
|
|
689
|
+
divergentDeriveAddresses.add(walletAddress);
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
setStoredKey(walletAddress, {
|
|
693
|
+
legacy: existing.legacy ?? legacyKey,
|
|
694
|
+
current: existing.current ?? currentKey
|
|
695
|
+
});
|
|
696
|
+
} else {
|
|
697
|
+
setStoredKey(walletAddress, { legacy: legacyKey, current: currentKey });
|
|
643
698
|
}
|
|
644
|
-
|
|
699
|
+
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
700
|
+
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
701
|
+
refreshCandidatesByAddress.delete(walletAddress);
|
|
702
|
+
divergentDeriveAddresses.delete(walletAddress);
|
|
645
703
|
notifyKeyAvailable(walletAddress);
|
|
704
|
+
return true;
|
|
646
705
|
})();
|
|
647
706
|
pendingKeyRequests.set(walletAddress, promise);
|
|
648
707
|
try {
|
|
649
|
-
await promise;
|
|
708
|
+
return await promise;
|
|
650
709
|
} finally {
|
|
651
710
|
if (pendingKeyRequests.get(walletAddress) === promise) {
|
|
652
711
|
pendingKeyRequests.delete(walletAddress);
|
|
653
712
|
}
|
|
654
713
|
}
|
|
655
714
|
}
|
|
715
|
+
async function refreshEncryptionKeyIfMatches(walletAddress, probeCiphertext, signMessage, embeddedWalletSigner) {
|
|
716
|
+
if (!isValidWalletAddress(walletAddress)) {
|
|
717
|
+
throw new Error(
|
|
718
|
+
`Invalid wallet address: ${walletAddress}. Address must start with 0x and be 42 characters (0x + 40 hex characters).`
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
const parsed = parsePrefixedCiphertext(probeCiphertext);
|
|
722
|
+
if (!parsed) {
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
const cached = refreshCandidatesByAddress.get(walletAddress);
|
|
726
|
+
if (cached) {
|
|
727
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, cached);
|
|
728
|
+
}
|
|
729
|
+
let derivePromise = pendingCandidateDerives.get(walletAddress);
|
|
730
|
+
if (!derivePromise) {
|
|
731
|
+
derivePromise = (async () => {
|
|
732
|
+
const candidates2 = await deriveRefreshCandidates(signMessage, embeddedWalletSigner);
|
|
733
|
+
if (candidates2) {
|
|
734
|
+
refreshCandidatesByAddress.set(walletAddress, candidates2);
|
|
735
|
+
}
|
|
736
|
+
return candidates2;
|
|
737
|
+
})().finally(() => {
|
|
738
|
+
if (pendingCandidateDerives.get(walletAddress) === derivePromise) {
|
|
739
|
+
pendingCandidateDerives.delete(walletAddress);
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
pendingCandidateDerives.set(walletAddress, derivePromise);
|
|
743
|
+
}
|
|
744
|
+
const candidates = await derivePromise;
|
|
745
|
+
if (!candidates) {
|
|
746
|
+
return false;
|
|
747
|
+
}
|
|
748
|
+
return tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates);
|
|
749
|
+
}
|
|
750
|
+
function parsePrefixedCiphertext(probeCiphertext) {
|
|
751
|
+
const version = probeCiphertext.startsWith("enc:v3:") ? "v3" : probeCiphertext.startsWith("enc:v2:") ? "v2" : null;
|
|
752
|
+
if (!version) return null;
|
|
753
|
+
const encryptedData = probeCiphertext.slice(
|
|
754
|
+
version === "v3" ? "enc:v3:".length : "enc:v2:".length
|
|
755
|
+
);
|
|
756
|
+
if (encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(encryptedData)) {
|
|
757
|
+
return null;
|
|
758
|
+
}
|
|
759
|
+
return { version, encryptedData };
|
|
760
|
+
}
|
|
761
|
+
async function deriveRefreshCandidates(signMessage, embeddedWalletSigner) {
|
|
762
|
+
const startEpoch = sessionEpoch;
|
|
763
|
+
const signOptions = { showWalletUIs: false };
|
|
764
|
+
let signature;
|
|
765
|
+
try {
|
|
766
|
+
if (embeddedWalletSigner) {
|
|
767
|
+
signature = await embeddedWalletSigner(SIGN_MESSAGE, signOptions);
|
|
768
|
+
} else {
|
|
769
|
+
signature = await signMessage(SIGN_MESSAGE, signOptions);
|
|
770
|
+
}
|
|
771
|
+
} catch (error) {
|
|
772
|
+
if (embeddedWalletSigner && error instanceof Error) {
|
|
773
|
+
getLogger().warn(
|
|
774
|
+
"Embedded wallet signing failed during key refresh, falling back to standard signMessage:",
|
|
775
|
+
error.message
|
|
776
|
+
);
|
|
777
|
+
signature = await signMessage(SIGN_MESSAGE, signOptions);
|
|
778
|
+
} else {
|
|
779
|
+
throw error;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
const [legacyKey, currentKey] = await Promise.all([
|
|
783
|
+
deriveKeyFromSignature(signature),
|
|
784
|
+
deriveKeyFromSignatureV3(signature)
|
|
785
|
+
]);
|
|
786
|
+
if (sessionEpoch !== startEpoch) {
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
return { legacy: legacyKey, current: currentKey };
|
|
790
|
+
}
|
|
791
|
+
async function tryCommitCandidatesIfProbeMatches(walletAddress, parsed, candidates) {
|
|
792
|
+
const candidateHex = parsed.version === "v2" ? candidates.legacy : candidates.current;
|
|
793
|
+
const keyBytes = hexToBytes(candidateHex);
|
|
794
|
+
const candidateCryptoKey = await crypto.subtle.importKey(
|
|
795
|
+
"raw",
|
|
796
|
+
keyBytes.buffer,
|
|
797
|
+
{ name: "AES-GCM" },
|
|
798
|
+
false,
|
|
799
|
+
["encrypt", "decrypt"]
|
|
800
|
+
);
|
|
801
|
+
try {
|
|
802
|
+
await decryptDataWithKey(parsed.encryptedData, candidateCryptoKey);
|
|
803
|
+
} catch {
|
|
804
|
+
getLogger().warn(
|
|
805
|
+
"refreshEncryptionKeyIfMatches: candidate keys failed to decrypt probe; leaving store unchanged"
|
|
806
|
+
);
|
|
807
|
+
return false;
|
|
808
|
+
}
|
|
809
|
+
setStoredKey(walletAddress, { legacy: candidates.legacy, current: candidates.current });
|
|
810
|
+
cryptoKeyCache.delete(`${walletAddress}:v2`);
|
|
811
|
+
cryptoKeyCache.delete(`${walletAddress}:v3`);
|
|
812
|
+
divergentDeriveAddresses.delete(walletAddress);
|
|
813
|
+
notifyKeyAvailable(walletAddress);
|
|
814
|
+
return true;
|
|
815
|
+
}
|
|
656
816
|
async function persistKeyPair(address, startEpoch) {
|
|
657
817
|
if (typeof window === "undefined") {
|
|
658
818
|
return;
|
|
@@ -886,15 +1046,28 @@ function useEncryption(signMessage, embeddedWalletSigner) {
|
|
|
886
1046
|
clearKeyPair: (walletAddress) => clearKeyPair(walletAddress)
|
|
887
1047
|
};
|
|
888
1048
|
}
|
|
889
|
-
var SIGN_MESSAGE, encryptionKeyStore, pendingKeyRequests, sessionEpoch, cryptoKeyCache, keyAvailableCallbacks, clearAllEncryptionStateCallbacks, keyPairStore, SHARED_TEXT_ENCODER, SHARED_TEXT_DECODER, KEYPAIR_STORAGE_PREFIX;
|
|
1049
|
+
var SIGN_MESSAGE, EncryptionKeyMissingError, encryptionKeyStore, pendingKeyRequests, pendingCandidateDerives, refreshCandidatesByAddress, divergentDeriveAddresses, sessionEpoch, cryptoKeyCache, keyAvailableCallbacks, clearAllEncryptionStateCallbacks, keyPairStore, SHARED_TEXT_ENCODER, SHARED_TEXT_DECODER, AES_256_KEY_HEX, KEYPAIR_STORAGE_PREFIX;
|
|
890
1050
|
var init_useEncryption = __esm({
|
|
891
1051
|
"src/react/useEncryption.ts"() {
|
|
892
1052
|
"use strict";
|
|
893
1053
|
"use client";
|
|
894
1054
|
init_logger();
|
|
895
1055
|
SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
|
|
1056
|
+
EncryptionKeyMissingError = class extends Error {
|
|
1057
|
+
constructor(address, version) {
|
|
1058
|
+
super(
|
|
1059
|
+
`Encryption key (${version}) not found for ${address}. Please sign a message to generate your encryption key.`
|
|
1060
|
+
);
|
|
1061
|
+
this.name = "EncryptionKeyMissingError";
|
|
1062
|
+
this.address = address;
|
|
1063
|
+
this.version = version;
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
896
1066
|
encryptionKeyStore = /* @__PURE__ */ new Map();
|
|
897
1067
|
pendingKeyRequests = /* @__PURE__ */ new Map();
|
|
1068
|
+
pendingCandidateDerives = /* @__PURE__ */ new Map();
|
|
1069
|
+
refreshCandidatesByAddress = /* @__PURE__ */ new Map();
|
|
1070
|
+
divergentDeriveAddresses = /* @__PURE__ */ new Set();
|
|
898
1071
|
sessionEpoch = 0;
|
|
899
1072
|
cryptoKeyCache = /* @__PURE__ */ new Map();
|
|
900
1073
|
keyAvailableCallbacks = /* @__PURE__ */ new Map();
|
|
@@ -902,6 +1075,7 @@ var init_useEncryption = __esm({
|
|
|
902
1075
|
keyPairStore = /* @__PURE__ */ new Map();
|
|
903
1076
|
SHARED_TEXT_ENCODER = new TextEncoder();
|
|
904
1077
|
SHARED_TEXT_DECODER = new TextDecoder();
|
|
1078
|
+
AES_256_KEY_HEX = /^[0-9a-fA-F]{64}$/;
|
|
905
1079
|
KEYPAIR_STORAGE_PREFIX = "ecdh_keypair_";
|
|
906
1080
|
}
|
|
907
1081
|
});
|
|
@@ -954,20 +1128,29 @@ async function encryptField(value, address, signMessage, embeddedWalletSigner, s
|
|
|
954
1128
|
const encrypted = await encryptData(value, address);
|
|
955
1129
|
return `${ENCRYPTION_PREFIX}${encrypted}`;
|
|
956
1130
|
}
|
|
957
|
-
async function
|
|
958
|
-
if (!value) return value;
|
|
1131
|
+
async function decryptFieldDetailed(value, address) {
|
|
1132
|
+
if (!value) return { status: "plaintext", value };
|
|
959
1133
|
const detected = detectEncryptionVersion(value);
|
|
960
|
-
if (!detected) return value;
|
|
1134
|
+
if (!detected) return { status: "plaintext", value };
|
|
961
1135
|
if (detected.encryptedData.length < 56 || !/^[0-9a-f]+$/i.test(detected.encryptedData)) {
|
|
962
|
-
return value;
|
|
1136
|
+
return { status: "invalid_payload", value, version: detected.version };
|
|
963
1137
|
}
|
|
964
1138
|
try {
|
|
965
|
-
|
|
1139
|
+
const plaintext = await decryptData(detected.encryptedData, address, detected.version);
|
|
1140
|
+
return { status: "ok", value: plaintext, version: detected.version };
|
|
966
1141
|
} catch (error) {
|
|
967
|
-
|
|
968
|
-
|
|
1142
|
+
if (error instanceof EncryptionKeyMissingError) {
|
|
1143
|
+
getLogger().warn("Failed to decrypt field (key missing for version):", error.message);
|
|
1144
|
+
return { status: "key_missing", value, version: detected.version };
|
|
1145
|
+
}
|
|
1146
|
+
getLogger().warn("Failed to decrypt field (auth mismatch or crypto error):", error);
|
|
1147
|
+
return { status: "auth_mismatch", value, version: detected.version };
|
|
969
1148
|
}
|
|
970
1149
|
}
|
|
1150
|
+
async function decryptField(value, address) {
|
|
1151
|
+
const result = await decryptFieldDetailed(value, address);
|
|
1152
|
+
return result.value;
|
|
1153
|
+
}
|
|
971
1154
|
async function encryptJsonField(value, address, signMessage, embeddedWalletSigner, skipKeyRequest) {
|
|
972
1155
|
if (!value) return void 0;
|
|
973
1156
|
const jsonString = JSON.stringify(value);
|
|
@@ -1084,20 +1267,40 @@ async function encryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
1084
1267
|
throw error;
|
|
1085
1268
|
}
|
|
1086
1269
|
}
|
|
1087
|
-
async function
|
|
1088
|
-
if (value === void 0) return void 0;
|
|
1089
|
-
if (value === null) return value;
|
|
1270
|
+
async function decryptMaybeJsonFieldDetailed(value, address) {
|
|
1271
|
+
if (value === void 0) return { value: void 0, status: "plaintext" };
|
|
1272
|
+
if (value === null) return { value, status: "plaintext" };
|
|
1090
1273
|
if (typeof value === "string") {
|
|
1091
1274
|
if (isEncrypted(value)) {
|
|
1092
|
-
|
|
1275
|
+
const detailed = await decryptFieldDetailed(value, address);
|
|
1276
|
+
if (detailed.status !== "ok") {
|
|
1277
|
+
return { value: void 0, status: detailed.status, probe: value };
|
|
1278
|
+
}
|
|
1279
|
+
try {
|
|
1280
|
+
return { value: JSON.parse(detailed.value), status: "ok" };
|
|
1281
|
+
} catch (error) {
|
|
1282
|
+
getLogger().warn("Failed to parse decrypted JSON field:", error);
|
|
1283
|
+
return { value: void 0, status: "invalid_payload", probe: value };
|
|
1284
|
+
}
|
|
1093
1285
|
}
|
|
1094
1286
|
try {
|
|
1095
|
-
return JSON.parse(value);
|
|
1287
|
+
return { value: JSON.parse(value), status: "plaintext" };
|
|
1096
1288
|
} catch {
|
|
1097
|
-
return void 0;
|
|
1289
|
+
return { value: void 0, status: "plaintext" };
|
|
1098
1290
|
}
|
|
1099
1291
|
}
|
|
1100
|
-
return value;
|
|
1292
|
+
return { value, status: "plaintext" };
|
|
1293
|
+
}
|
|
1294
|
+
function worseDecryptStatus(a, b) {
|
|
1295
|
+
if (b === "ok" || b === "plaintext") return a;
|
|
1296
|
+
if (!a || a === "ok" || a === "plaintext") return b;
|
|
1297
|
+
const rank = (s) => {
|
|
1298
|
+
if (s === "auth_mismatch") return 3;
|
|
1299
|
+
if (s === "key_missing") return 2;
|
|
1300
|
+
if (s === "invalid_payload") return 1;
|
|
1301
|
+
return 0;
|
|
1302
|
+
};
|
|
1303
|
+
return rank(b) >= rank(a) ? b : a;
|
|
1101
1304
|
}
|
|
1102
1305
|
async function decryptMessageFields(message, address, signMessage, embeddedWalletSigner) {
|
|
1103
1306
|
if (!address) {
|
|
@@ -1110,33 +1313,82 @@ async function decryptMessageFields(message, address, signMessage, embeddedWalle
|
|
|
1110
1313
|
getLogger().warn("Failed to request encryption key for decryption:", error);
|
|
1111
1314
|
}
|
|
1112
1315
|
}
|
|
1113
|
-
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1316
|
+
let assembled = await assembleDecryptedMessage(message, address);
|
|
1317
|
+
const needsRefresh = assembled.decryptionStatus === "auth_mismatch" || assembled.decryptionStatus === "key_missing";
|
|
1318
|
+
if (needsRefresh && signMessage && assembled.refreshProbe) {
|
|
1319
|
+
try {
|
|
1320
|
+
const refreshed = await refreshEncryptionKeyIfMatches(
|
|
1321
|
+
address,
|
|
1322
|
+
assembled.refreshProbe,
|
|
1323
|
+
signMessage,
|
|
1324
|
+
embeddedWalletSigner
|
|
1325
|
+
);
|
|
1326
|
+
if (refreshed) {
|
|
1327
|
+
assembled = await assembleDecryptedMessage(message, address);
|
|
1328
|
+
}
|
|
1329
|
+
} catch (error) {
|
|
1330
|
+
getLogger().warn("Failed to refresh encryption key after decrypt failure:", error);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
const { refreshProbe: _probe, ...result } = assembled;
|
|
1334
|
+
return result;
|
|
1335
|
+
}
|
|
1336
|
+
async function assembleDecryptedMessage(message, address) {
|
|
1337
|
+
const contentResult = await decryptFieldDetailed(message.content, address);
|
|
1338
|
+
const thinkingResult = message.thinking ? await decryptFieldDetailed(message.thinking, address) : null;
|
|
1339
|
+
const vectorResult = await decryptMaybeJsonFieldDetailed(
|
|
1116
1340
|
message.vector,
|
|
1117
1341
|
address
|
|
1118
1342
|
);
|
|
1119
|
-
const
|
|
1343
|
+
const chunksResult = await decryptMaybeJsonFieldDetailed(
|
|
1120
1344
|
message.chunks,
|
|
1121
1345
|
address
|
|
1122
1346
|
);
|
|
1123
|
-
const
|
|
1347
|
+
const sourcesResult = await decryptMaybeJsonFieldDetailed(
|
|
1124
1348
|
message.sources,
|
|
1125
1349
|
address
|
|
1126
1350
|
);
|
|
1127
|
-
const
|
|
1351
|
+
const thoughtProcessResult = await decryptMaybeJsonFieldDetailed(
|
|
1128
1352
|
message.thoughtProcess,
|
|
1129
1353
|
address
|
|
1130
1354
|
);
|
|
1131
|
-
|
|
1355
|
+
let decryptionStatus;
|
|
1356
|
+
let refreshProbe;
|
|
1357
|
+
const consider = (status, probe) => {
|
|
1358
|
+
decryptionStatus = worseDecryptStatus(decryptionStatus, status);
|
|
1359
|
+
if (!refreshProbe && probe && (status === "auth_mismatch" || status === "key_missing")) {
|
|
1360
|
+
refreshProbe = probe;
|
|
1361
|
+
}
|
|
1362
|
+
};
|
|
1363
|
+
consider(contentResult.status, isEncrypted(message.content) ? message.content : void 0);
|
|
1364
|
+
if (thinkingResult && message.thinking && typeof message.thinking === "string") {
|
|
1365
|
+
consider(thinkingResult.status, isEncrypted(message.thinking) ? message.thinking : void 0);
|
|
1366
|
+
}
|
|
1367
|
+
if (vectorResult.probe) consider(vectorResult.status, vectorResult.probe);
|
|
1368
|
+
if (chunksResult.probe) consider(chunksResult.status, chunksResult.probe);
|
|
1369
|
+
if (sourcesResult.probe) consider(sourcesResult.status, sourcesResult.probe);
|
|
1370
|
+
if (thoughtProcessResult.probe) {
|
|
1371
|
+
consider(thoughtProcessResult.status, thoughtProcessResult.probe);
|
|
1372
|
+
}
|
|
1373
|
+
const statusForConsumer = decryptionStatus === "ok" || decryptionStatus === "plaintext" || !decryptionStatus ? void 0 : decryptionStatus;
|
|
1374
|
+
const result = {
|
|
1132
1375
|
...message,
|
|
1133
|
-
content:
|
|
1134
|
-
thinking:
|
|
1135
|
-
vector:
|
|
1136
|
-
chunks:
|
|
1137
|
-
sources:
|
|
1138
|
-
thoughtProcess:
|
|
1376
|
+
content: contentResult.value,
|
|
1377
|
+
thinking: thinkingResult ? thinkingResult.value : message.thinking,
|
|
1378
|
+
vector: vectorResult.value,
|
|
1379
|
+
chunks: chunksResult.value,
|
|
1380
|
+
sources: sourcesResult.value,
|
|
1381
|
+
thoughtProcess: thoughtProcessResult.value
|
|
1139
1382
|
};
|
|
1383
|
+
if (statusForConsumer) {
|
|
1384
|
+
result.decryptionStatus = statusForConsumer;
|
|
1385
|
+
} else {
|
|
1386
|
+
delete result.decryptionStatus;
|
|
1387
|
+
}
|
|
1388
|
+
if (refreshProbe) {
|
|
1389
|
+
result.refreshProbe = refreshProbe;
|
|
1390
|
+
}
|
|
1391
|
+
return result;
|
|
1140
1392
|
}
|
|
1141
1393
|
var init_encryption = __esm({
|
|
1142
1394
|
"src/lib/db/chat/encryption.ts"() {
|
|
@@ -8938,6 +9190,7 @@ __export(index_exports, {
|
|
|
8938
9190
|
DropboxAuthProvider: () => DropboxAuthProvider,
|
|
8939
9191
|
ENTITY_FANOUT: () => ENTITY_FANOUT,
|
|
8940
9192
|
ENTITY_KINDS: () => ENTITY_KINDS,
|
|
9193
|
+
EncryptionKeyMissingError: () => EncryptionKeyMissingError,
|
|
8941
9194
|
EntityModel: () => Entity,
|
|
8942
9195
|
ExcelProcessor: () => ExcelProcessor,
|
|
8943
9196
|
FILE_PLACEHOLDER_PREFIX: () => FILE_PLACEHOLDER_PREFIX,
|
|
@@ -9228,6 +9481,7 @@ __export(index_exports, {
|
|
|
9228
9481
|
reflect: () => reflect,
|
|
9229
9482
|
refreshCalendarToken: () => refreshCalendarToken,
|
|
9230
9483
|
refreshDriveToken: () => refreshDriveToken,
|
|
9484
|
+
refreshEncryptionKeyIfMatches: () => refreshEncryptionKeyIfMatches,
|
|
9231
9485
|
refreshGithubToken: () => refreshGithubToken,
|
|
9232
9486
|
refreshNotionToken: () => refreshNotionToken,
|
|
9233
9487
|
relinkMemoryTopicsOp: () => relinkMemoryTopicsOp,
|
|
@@ -9259,6 +9513,7 @@ __export(index_exports, {
|
|
|
9259
9513
|
searchMediaOp: () => searchMediaOp,
|
|
9260
9514
|
searchMessagesOp: () => searchMessagesOp,
|
|
9261
9515
|
searchVaultMemories: () => searchVaultMemories,
|
|
9516
|
+
seedEncryptionKeys: () => seedEncryptionKeys,
|
|
9262
9517
|
selectServerToolsForPrompt: () => selectServerToolsForPrompt,
|
|
9263
9518
|
serializeJsx: () => serializeJsx,
|
|
9264
9519
|
setLogger: () => setLogger,
|
|
@@ -33898,6 +34153,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
33898
34153
|
DropboxAuthProvider,
|
|
33899
34154
|
ENTITY_FANOUT,
|
|
33900
34155
|
ENTITY_KINDS,
|
|
34156
|
+
EncryptionKeyMissingError,
|
|
33901
34157
|
EntityModel,
|
|
33902
34158
|
ExcelProcessor,
|
|
33903
34159
|
FILE_PLACEHOLDER_PREFIX,
|
|
@@ -34188,6 +34444,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
34188
34444
|
reflect,
|
|
34189
34445
|
refreshCalendarToken,
|
|
34190
34446
|
refreshDriveToken,
|
|
34447
|
+
refreshEncryptionKeyIfMatches,
|
|
34191
34448
|
refreshGithubToken,
|
|
34192
34449
|
refreshNotionToken,
|
|
34193
34450
|
relinkMemoryTopicsOp,
|
|
@@ -34219,6 +34476,7 @@ function renderAnumaJsx(jsx3) {
|
|
|
34219
34476
|
searchMediaOp,
|
|
34220
34477
|
searchMessagesOp,
|
|
34221
34478
|
searchVaultMemories,
|
|
34479
|
+
seedEncryptionKeys,
|
|
34222
34480
|
selectServerToolsForPrompt,
|
|
34223
34481
|
serializeJsx,
|
|
34224
34482
|
setLogger,
|