@reverbia/sdk 1.0.0-next.20251229084841 → 1.1.0-next.20251230221037

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.
@@ -1,13 +1,32 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __decorateClass = (decorators, target, key, kind) => {
4
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
- if (decorator = decorators[i])
7
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result) __defProp(target, key, result);
9
- return result;
10
- };
1
+ import {
2
+ clearTokenData,
3
+ getRefreshToken,
4
+ getRefreshTokenSync,
5
+ getStoredTokenData,
6
+ getStoredTokenDataSync,
7
+ getValidAccessToken,
8
+ getValidAccessTokenSync,
9
+ hasStoredCredentialsSync,
10
+ isTokenExpired,
11
+ storeTokenData,
12
+ tokenResponseToStoredData
13
+ } from "./chunk-KUFGQF6E.mjs";
14
+ import {
15
+ __decorateClass,
16
+ clearAllEncryptionKeys,
17
+ clearAllKeyPairs,
18
+ clearEncryptionKey,
19
+ clearKeyPair,
20
+ decryptData,
21
+ decryptDataBytes,
22
+ encryptData,
23
+ exportPublicKey,
24
+ hasEncryptionKey,
25
+ hasKeyPair,
26
+ requestEncryptionKey,
27
+ requestKeyPair,
28
+ useEncryption
29
+ } from "./chunk-T56Y62G7.mjs";
11
30
 
12
31
  // src/react/useChat.ts
13
32
  import { useCallback, useEffect, useRef, useState } from "react";
@@ -1229,123 +1248,6 @@ function useChat(options) {
1229
1248
  };
1230
1249
  }
1231
1250
 
1232
- // src/react/useEncryption.ts
1233
- var SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
1234
- var encryptionKeyStore = /* @__PURE__ */ new Map();
1235
- function getStoredKey(address) {
1236
- return encryptionKeyStore.get(address) ?? null;
1237
- }
1238
- function setStoredKey(address, keyHex) {
1239
- encryptionKeyStore.set(address, keyHex);
1240
- }
1241
- function clearEncryptionKey(address) {
1242
- encryptionKeyStore.delete(address);
1243
- }
1244
- function clearAllEncryptionKeys() {
1245
- encryptionKeyStore.clear();
1246
- }
1247
- function hexToBytes(hex) {
1248
- const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
1249
- const bytes = new Uint8Array(cleanHex.length / 2);
1250
- for (let i = 0; i < cleanHex.length; i += 2) {
1251
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
1252
- }
1253
- return bytes;
1254
- }
1255
- function bytesToHex(bytes) {
1256
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1257
- }
1258
- async function deriveKeyFromSignature(signature) {
1259
- const sigBytes = hexToBytes(signature);
1260
- const hashBuffer = await crypto.subtle.digest(
1261
- "SHA-256",
1262
- sigBytes.buffer
1263
- );
1264
- const hashBytes = new Uint8Array(hashBuffer);
1265
- return bytesToHex(hashBytes);
1266
- }
1267
- async function getEncryptionKey(address) {
1268
- const keyHex = getStoredKey(address);
1269
- if (!keyHex) {
1270
- throw new Error(
1271
- "Encryption key not found. Please sign a message to generate your encryption key."
1272
- );
1273
- }
1274
- const keyBytes = hexToBytes(keyHex);
1275
- return crypto.subtle.importKey(
1276
- "raw",
1277
- keyBytes.buffer,
1278
- { name: "AES-GCM" },
1279
- false,
1280
- ["encrypt", "decrypt"]
1281
- );
1282
- }
1283
- async function encryptData(plaintext, address) {
1284
- const key = await getEncryptionKey(address);
1285
- const plaintextBytes = typeof plaintext === "string" ? new TextEncoder().encode(plaintext) : plaintext;
1286
- const iv = crypto.getRandomValues(new Uint8Array(12));
1287
- const encryptedData = await crypto.subtle.encrypt(
1288
- {
1289
- name: "AES-GCM",
1290
- iv
1291
- },
1292
- key,
1293
- plaintextBytes.buffer
1294
- );
1295
- const encryptedBytes = new Uint8Array(encryptedData);
1296
- const combined = new Uint8Array(iv.length + encryptedBytes.length);
1297
- combined.set(iv, 0);
1298
- combined.set(encryptedBytes, iv.length);
1299
- return bytesToHex(combined);
1300
- }
1301
- async function decryptData(encryptedHex, address) {
1302
- const key = await getEncryptionKey(address);
1303
- const combined = hexToBytes(encryptedHex);
1304
- const iv = combined.slice(0, 12);
1305
- const encryptedData = combined.slice(12);
1306
- const decryptedData = await crypto.subtle.decrypt(
1307
- {
1308
- name: "AES-GCM",
1309
- iv
1310
- },
1311
- key,
1312
- encryptedData
1313
- );
1314
- return new TextDecoder().decode(decryptedData);
1315
- }
1316
- async function decryptDataBytes(encryptedHex, address) {
1317
- const key = await getEncryptionKey(address);
1318
- const combined = hexToBytes(encryptedHex);
1319
- const iv = combined.slice(0, 12);
1320
- const encryptedData = combined.slice(12);
1321
- const decryptedData = await crypto.subtle.decrypt(
1322
- {
1323
- name: "AES-GCM",
1324
- iv
1325
- },
1326
- key,
1327
- encryptedData
1328
- );
1329
- return new Uint8Array(decryptedData);
1330
- }
1331
- function hasEncryptionKey(address) {
1332
- return getStoredKey(address) !== null;
1333
- }
1334
- async function requestEncryptionKey(walletAddress, signMessage) {
1335
- const existingKey = getStoredKey(walletAddress);
1336
- if (existingKey) {
1337
- return;
1338
- }
1339
- const signature = await signMessage(SIGN_MESSAGE);
1340
- const encryptionKey = await deriveKeyFromSignature(signature);
1341
- setStoredKey(walletAddress, encryptionKey);
1342
- }
1343
- function useEncryption(signMessage) {
1344
- return {
1345
- requestEncryptionKey: (walletAddress) => requestEncryptionKey(walletAddress, signMessage)
1346
- };
1347
- }
1348
-
1349
1251
  // src/react/useChatStorage.ts
1350
1252
  import { useCallback as useCallback2, useState as useState2, useMemo } from "react";
1351
1253
 
@@ -2420,7 +2322,7 @@ var sdkModelClasses = [
2420
2322
  ];
2421
2323
 
2422
2324
  // src/react/useMemoryStorage.ts
2423
- import { useCallback as useCallback3, useState as useState3, useMemo as useMemo2, useRef as useRef2 } from "react";
2325
+ import { useCallback as useCallback3, useState as useState3, useMemo as useMemo2, useRef as useRef2, useEffect as useEffect2 } from "react";
2424
2326
  import { postApiV1ChatCompletions } from "@reverbia/sdk";
2425
2327
 
2426
2328
  // src/lib/db/memory/schema.ts
@@ -2528,6 +2430,24 @@ async function getMemoriesByKeyOp(ctx, namespace, key) {
2528
2430
  return results.map(memoryToStored);
2529
2431
  }
2530
2432
  async function saveMemoryOp(ctx, opts) {
2433
+ if (!opts.namespace || typeof opts.namespace !== "string") {
2434
+ throw new Error("Namespace is required and must be a string");
2435
+ }
2436
+ if (!opts.key || typeof opts.key !== "string") {
2437
+ throw new Error("Key is required and must be a string");
2438
+ }
2439
+ if (!opts.value || typeof opts.value !== "string") {
2440
+ throw new Error("Value is required and must be a string");
2441
+ }
2442
+ if (!opts.type || typeof opts.type !== "string") {
2443
+ throw new Error("Type is required and must be a string");
2444
+ }
2445
+ if (typeof opts.confidence !== "number" || opts.confidence < 0 || opts.confidence > 1) {
2446
+ throw new Error("Confidence must be a number between 0 and 1");
2447
+ }
2448
+ if (typeof opts.pii !== "boolean") {
2449
+ throw new Error("PII must be a boolean");
2450
+ }
2531
2451
  const compositeKey = generateCompositeKey(opts.namespace, opts.key);
2532
2452
  const uniqueKey = generateUniqueKey(opts.namespace, opts.key, opts.value);
2533
2453
  const result = await ctx.database.write(async () => {
@@ -2962,6 +2882,275 @@ var generateEmbeddingForMemory = async (memory, options = {}) => {
2962
2882
  return generateEmbeddingForText(text4, options);
2963
2883
  };
2964
2884
 
2885
+ // src/lib/db/migration.ts
2886
+ var ENCRYPTION_PREFIX_V1 = "enc:v1:";
2887
+ var ENCRYPTION_PREFIX_V2 = "enc:v2:";
2888
+ var ENCRYPTION_PREFIX_LEGACY = "enc:";
2889
+ function getEncryptionVersion(value) {
2890
+ if (value.startsWith(ENCRYPTION_PREFIX_V2)) return "v2";
2891
+ if (value.startsWith(ENCRYPTION_PREFIX_V1)) return "v1";
2892
+ if (value.startsWith(ENCRYPTION_PREFIX_LEGACY)) return "v1";
2893
+ return null;
2894
+ }
2895
+ function isOldEncryption(value) {
2896
+ const version2 = getEncryptionVersion(value);
2897
+ return version2 === "v1";
2898
+ }
2899
+ async function encryptNewValue(plaintext, walletAddress) {
2900
+ if (!hasEncryptionKey(walletAddress)) {
2901
+ throw new Error("Encryption key not available for new scheme");
2902
+ }
2903
+ const encrypted = await encryptData(plaintext, walletAddress);
2904
+ return `enc:v2:${encrypted}`;
2905
+ }
2906
+ async function migrateEncryptedValue(encryptedValue, walletAddress, signMessage) {
2907
+ if (getEncryptionVersion(encryptedValue) === "v2") {
2908
+ return encryptedValue;
2909
+ }
2910
+ if (!getEncryptionVersion(encryptedValue)) {
2911
+ return encryptedValue;
2912
+ }
2913
+ if (!hasEncryptionKey(walletAddress)) {
2914
+ const { requestEncryptionKey: requestEncryptionKey2 } = await import("./useEncryption-5RTXKDNZ.mjs");
2915
+ await requestEncryptionKey2(walletAddress, signMessage);
2916
+ if (!hasEncryptionKey(walletAddress)) {
2917
+ throw new Error("Encryption key not available after signing");
2918
+ }
2919
+ }
2920
+ let encryptedPayload;
2921
+ if (encryptedValue.startsWith(ENCRYPTION_PREFIX_V1)) {
2922
+ encryptedPayload = encryptedValue.slice(ENCRYPTION_PREFIX_V1.length);
2923
+ } else if (encryptedValue.startsWith(ENCRYPTION_PREFIX_LEGACY)) {
2924
+ encryptedPayload = encryptedValue.slice(ENCRYPTION_PREFIX_LEGACY.length);
2925
+ } else {
2926
+ throw new Error("Invalid old encryption format");
2927
+ }
2928
+ const plaintext = await decryptData(encryptedPayload, walletAddress);
2929
+ return await encryptNewValue(plaintext, walletAddress);
2930
+ }
2931
+
2932
+ // src/lib/db/memory/encryption.ts
2933
+ var ENCRYPTED_FIELDS = ["value", "rawEvidence", "key", "namespace"];
2934
+ var ENCRYPTION_PREFIX_V12 = "enc:v1:";
2935
+ var ENCRYPTION_PREFIX_V22 = "enc:v2:";
2936
+ var ENCRYPTION_PREFIX_LEGACY2 = "enc:";
2937
+ var CURRENT_ENCRYPTION_VERSION = "v2";
2938
+ var ENCRYPTION_PREFIX = `enc:${CURRENT_ENCRYPTION_VERSION}:`;
2939
+ var MAX_FIELD_SIZE = 1024 * 1024;
2940
+ function isEncrypted(value) {
2941
+ return value.startsWith(ENCRYPTION_PREFIX) || value.startsWith(ENCRYPTION_PREFIX_V12) || value.startsWith(ENCRYPTION_PREFIX_LEGACY2);
2942
+ }
2943
+ function getEncryptionVersion2(value) {
2944
+ if (value.startsWith(ENCRYPTION_PREFIX_V22)) return "v2";
2945
+ if (value.startsWith(ENCRYPTION_PREFIX_V12)) return "v1";
2946
+ if (value.startsWith(ENCRYPTION_PREFIX_LEGACY2)) return "v1";
2947
+ return null;
2948
+ }
2949
+ async function encryptField(value, address) {
2950
+ if (!value || isEncrypted(value)) {
2951
+ return value;
2952
+ }
2953
+ if (value.length > MAX_FIELD_SIZE) {
2954
+ throw new Error(
2955
+ `Field value too large: ${value.length} bytes (max: ${MAX_FIELD_SIZE} bytes)`
2956
+ );
2957
+ }
2958
+ try {
2959
+ const encrypted = await encryptData(value, address);
2960
+ return `${ENCRYPTION_PREFIX}${encrypted}`;
2961
+ } catch (error) {
2962
+ const message = error instanceof Error ? error.message : "Unknown encryption error";
2963
+ throw new Error(`Encryption failed: ${message}`);
2964
+ }
2965
+ }
2966
+ var DECRYPTION_FAILED_PLACEHOLDER = "[Decryption Failed]";
2967
+ async function decryptField(value, address, signMessage, onMigrated) {
2968
+ if (!value || !isEncrypted(value)) {
2969
+ return value;
2970
+ }
2971
+ try {
2972
+ if (isOldEncryption(value) && signMessage && onMigrated) {
2973
+ try {
2974
+ const migratedValue = await migrateEncryptedValue(value, address, signMessage);
2975
+ await onMigrated(migratedValue);
2976
+ const encryptedPayload2 = migratedValue.slice(ENCRYPTION_PREFIX_V22.length);
2977
+ return await decryptData(encryptedPayload2, address);
2978
+ } catch (migrationError) {
2979
+ const errorMessage = migrationError instanceof Error ? migrationError.message : "Unknown migration error";
2980
+ console.warn("Migration failed, attempting decryption with current key:", {
2981
+ error: errorMessage,
2982
+ address
2983
+ });
2984
+ }
2985
+ }
2986
+ let encryptedPayload;
2987
+ if (value.startsWith(ENCRYPTION_PREFIX_V22)) {
2988
+ encryptedPayload = value.slice(ENCRYPTION_PREFIX_V22.length);
2989
+ } else if (value.startsWith(ENCRYPTION_PREFIX_V12)) {
2990
+ encryptedPayload = value.slice(ENCRYPTION_PREFIX_V12.length);
2991
+ } else if (value.startsWith(ENCRYPTION_PREFIX_LEGACY2)) {
2992
+ encryptedPayload = value.slice(ENCRYPTION_PREFIX_LEGACY2.length);
2993
+ } else {
2994
+ return value;
2995
+ }
2996
+ return await decryptData(encryptedPayload, address);
2997
+ } catch (error) {
2998
+ const errorMessage = error instanceof Error ? error.message : "Unknown decryption error";
2999
+ console.error("Decryption failed for field:", {
3000
+ address,
3001
+ valueLength: value.length,
3002
+ error: errorMessage
3003
+ });
3004
+ throw new Error(`Decryption failed: ${errorMessage}`);
3005
+ }
3006
+ }
3007
+ async function encryptMemoryFields(memory, address) {
3008
+ const encrypted = { ...memory };
3009
+ const encryptionPromises = ENCRYPTED_FIELDS.map(async (field3) => {
3010
+ const value = memory[field3];
3011
+ if (typeof value === "string" && value.length > 0) {
3012
+ try {
3013
+ encrypted[field3] = await encryptField(value, address);
3014
+ } catch (error) {
3015
+ throw new Error(`Failed to encrypt field ${field3}: ${error instanceof Error ? error.message : "Unknown error"}`);
3016
+ }
3017
+ }
3018
+ });
3019
+ const results = await Promise.allSettled(encryptionPromises);
3020
+ const failures = results.filter((r) => r.status === "rejected");
3021
+ if (failures.length > 0) {
3022
+ const errorMessages = failures.map(
3023
+ (f) => f.status === "rejected" ? f.reason instanceof Error ? f.reason.message : String(f.reason) : ""
3024
+ ).join("; ");
3025
+ throw new Error(`Encryption failed for ${failures.length} field(s): ${errorMessages}`);
3026
+ }
3027
+ return encrypted;
3028
+ }
3029
+ async function decryptMemoryFields(memory, address, signMessage, updateMemory) {
3030
+ const decrypted = { ...memory };
3031
+ const decryptionPromises = ENCRYPTED_FIELDS.map(async (field3) => {
3032
+ const value = memory[field3];
3033
+ if (typeof value === "string" && value.length > 0) {
3034
+ if (!isEncrypted(value)) {
3035
+ if (updateMemory && memory.uniqueId) {
3036
+ try {
3037
+ const encryptedValue = await encryptField(value, address);
3038
+ await updateMemory(memory.uniqueId, {
3039
+ [field3]: encryptedValue
3040
+ });
3041
+ decrypted[field3] = value;
3042
+ } catch (error) {
3043
+ if (process.env.NODE_ENV === "development") {
3044
+ console.warn(`Failed to encrypt field ${field3}:`, error);
3045
+ }
3046
+ decrypted[field3] = value;
3047
+ }
3048
+ } else {
3049
+ decrypted[field3] = value;
3050
+ }
3051
+ } else {
3052
+ const onMigrated = updateMemory && memory.uniqueId ? async (migratedValue) => {
3053
+ await updateMemory(memory.uniqueId, {
3054
+ [field3]: migratedValue
3055
+ });
3056
+ } : void 0;
3057
+ decrypted[field3] = await decryptField(value, address, signMessage, onMigrated);
3058
+ }
3059
+ }
3060
+ });
3061
+ await Promise.all(decryptionPromises);
3062
+ return decrypted;
3063
+ }
3064
+ async function encryptMemoriesBatch(memories, address) {
3065
+ return Promise.all(
3066
+ memories.map((memory) => encryptMemoryFields(memory, address))
3067
+ );
3068
+ }
3069
+ async function decryptMemoriesBatch(memories, address, signMessage, updateMemory) {
3070
+ return Promise.all(
3071
+ memories.map(
3072
+ (memory) => decryptMemoryFields(memory, address, signMessage, updateMemory)
3073
+ )
3074
+ );
3075
+ }
3076
+ function hasEncryptedFields(memory) {
3077
+ return ENCRYPTED_FIELDS.some((field3) => {
3078
+ const value = memory[field3];
3079
+ return typeof value === "string" && isEncrypted(value);
3080
+ });
3081
+ }
3082
+ function needsEncryption(memory) {
3083
+ return ENCRYPTED_FIELDS.some((field3) => {
3084
+ const value = memory[field3];
3085
+ return typeof value === "string" && value.length > 0 && !isEncrypted(value);
3086
+ });
3087
+ }
3088
+ function extractMemoryFieldsForEncryption(memory) {
3089
+ return {
3090
+ type: memory.type,
3091
+ namespace: memory.namespace,
3092
+ key: memory.key,
3093
+ value: memory.value,
3094
+ rawEvidence: memory.rawEvidence,
3095
+ confidence: memory.confidence,
3096
+ pii: memory.pii
3097
+ };
3098
+ }
3099
+ async function retryEncryption(operation, maxRetries = 3, initialDelay = 500) {
3100
+ let lastError;
3101
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
3102
+ try {
3103
+ return await operation();
3104
+ } catch (error) {
3105
+ lastError = error;
3106
+ if (attempt === maxRetries) {
3107
+ throw lastError;
3108
+ }
3109
+ const delay = initialDelay * Math.pow(2, attempt);
3110
+ await new Promise((resolve) => setTimeout(resolve, delay));
3111
+ }
3112
+ }
3113
+ throw lastError;
3114
+ }
3115
+ async function encryptMemoriesBatchInPlace(memories, address, updateFn, batchSize = 5) {
3116
+ const failed = [];
3117
+ const errors = [];
3118
+ let success = 0;
3119
+ for (let i = 0; i < memories.length; i += batchSize) {
3120
+ const batch = memories.slice(i, i + batchSize);
3121
+ const results = await Promise.allSettled(
3122
+ batch.map(async (memory) => {
3123
+ await retryEncryption(async () => {
3124
+ const fields = extractMemoryFieldsForEncryption(memory);
3125
+ const encryptedData = await encryptMemoryFields(fields, address);
3126
+ await updateFn(memory.uniqueId, encryptedData);
3127
+ });
3128
+ })
3129
+ );
3130
+ results.forEach((result, index) => {
3131
+ if (result.status === "fulfilled") {
3132
+ success++;
3133
+ } else {
3134
+ const memory = batch[index];
3135
+ if (memory) {
3136
+ failed.push(memory.uniqueId);
3137
+ const errorMessage = result.reason instanceof Error ? result.reason.message : String(result.reason);
3138
+ errors.push({
3139
+ id: memory.uniqueId,
3140
+ error: errorMessage
3141
+ });
3142
+ console.error(
3143
+ "Failed to encrypt memory:",
3144
+ memory.uniqueId,
3145
+ errorMessage
3146
+ );
3147
+ }
3148
+ }
3149
+ });
3150
+ }
3151
+ return { success, failed, errors };
3152
+ }
3153
+
2965
3154
  // src/react/useMemoryStorage.ts
2966
3155
  function useMemoryStorage(options) {
2967
3156
  const {
@@ -2971,7 +3160,10 @@ function useMemoryStorage(options) {
2971
3160
  generateEmbeddings = true,
2972
3161
  onFactsExtracted,
2973
3162
  getToken,
2974
- baseUrl = BASE_URL
3163
+ baseUrl = BASE_URL,
3164
+ walletAddress,
3165
+ requestEncryptionKey: requestEncryptionKey2,
3166
+ signMessage
2975
3167
  } = options;
2976
3168
  const embeddingModel = userEmbeddingModel === void 0 ? DEFAULT_API_EMBEDDING_MODEL : userEmbeddingModel;
2977
3169
  const [memories, setMemories] = useState3([]);
@@ -2999,10 +3191,127 @@ function useMemoryStorage(options) {
2999
3191
  }),
3000
3192
  [effectiveEmbeddingModel, getToken, baseUrl]
3001
3193
  );
3194
+ const isEncryptionEnabled = useMemo2(
3195
+ () => !!walletAddress && !!requestEncryptionKey2,
3196
+ [walletAddress, requestEncryptionKey2]
3197
+ );
3198
+ const ensureEncryptionReady = useCallback3(async () => {
3199
+ if (!isEncryptionEnabled || !walletAddress) {
3200
+ return null;
3201
+ }
3202
+ if (hasEncryptionKey(walletAddress)) {
3203
+ return walletAddress;
3204
+ }
3205
+ if (requestEncryptionKey2) {
3206
+ try {
3207
+ await requestEncryptionKey2(walletAddress);
3208
+ return walletAddress;
3209
+ } catch {
3210
+ return null;
3211
+ }
3212
+ }
3213
+ return null;
3214
+ }, [isEncryptionEnabled, walletAddress, requestEncryptionKey2]);
3215
+ const getSignMessageForMigration = useCallback3(() => {
3216
+ return signMessage;
3217
+ }, [signMessage]);
3218
+ const encryptUnencryptedMemories = useCallback3(
3219
+ async (address) => {
3220
+ if (!isEncryptionEnabled) return;
3221
+ try {
3222
+ const allMemories = await getAllMemoriesOp(storageCtx);
3223
+ if (!allMemories || allMemories.length === 0) return;
3224
+ const memoriesToEncrypt = allMemories.filter(
3225
+ (m) => needsEncryption(m)
3226
+ );
3227
+ if (memoriesToEncrypt.length === 0) return;
3228
+ await encryptMemoriesBatchInPlace(
3229
+ memoriesToEncrypt,
3230
+ address,
3231
+ async (id, data) => {
3232
+ const result = await updateMemoryOp(storageCtx, id, data);
3233
+ if (!result.ok) {
3234
+ throw new Error(`Failed to update memory ${id}`);
3235
+ }
3236
+ }
3237
+ );
3238
+ } catch (error) {
3239
+ if (process.env.NODE_ENV === "development") {
3240
+ console.error("Failed to encrypt unencrypted memories:", error);
3241
+ }
3242
+ }
3243
+ },
3244
+ [isEncryptionEnabled, storageCtx]
3245
+ );
3246
+ const encryptionLockRef = useRef2(null);
3247
+ const autoEncryptionRunRef = useRef2(false);
3248
+ useEffect2(() => {
3249
+ if (!isEncryptionEnabled || !walletAddress) {
3250
+ autoEncryptionRunRef.current = false;
3251
+ encryptionLockRef.current = null;
3252
+ return;
3253
+ }
3254
+ if (encryptionLockRef.current) {
3255
+ encryptionLockRef.current.then(() => {
3256
+ if (isEncryptionEnabled && walletAddress && !autoEncryptionRunRef.current) {
3257
+ ensureEncryptionReady().then((address) => {
3258
+ if (address) {
3259
+ autoEncryptionRunRef.current = true;
3260
+ const encryptionPromise2 = encryptUnencryptedMemories(address).catch((err) => {
3261
+ if (process.env.NODE_ENV === "development") {
3262
+ console.error("Failed to automatically encrypt memories:", err);
3263
+ }
3264
+ }).finally(() => {
3265
+ encryptionLockRef.current = null;
3266
+ });
3267
+ encryptionLockRef.current = encryptionPromise2;
3268
+ }
3269
+ });
3270
+ }
3271
+ });
3272
+ return;
3273
+ }
3274
+ if (autoEncryptionRunRef.current) {
3275
+ return;
3276
+ }
3277
+ autoEncryptionRunRef.current = true;
3278
+ const encryptionPromise = ensureEncryptionReady().then((address) => {
3279
+ if (address) {
3280
+ return encryptUnencryptedMemories(address);
3281
+ }
3282
+ }).catch((err) => {
3283
+ if (process.env.NODE_ENV === "development") {
3284
+ console.error("Failed to automatically encrypt memories:", err);
3285
+ }
3286
+ }).finally(() => {
3287
+ encryptionLockRef.current = null;
3288
+ });
3289
+ encryptionLockRef.current = encryptionPromise;
3290
+ }, [isEncryptionEnabled, walletAddress, ensureEncryptionReady, encryptUnencryptedMemories]);
3002
3291
  const refreshMemories = useCallback3(async () => {
3003
3292
  const storedMemories = await getAllMemoriesOp(storageCtx);
3293
+ if (isEncryptionEnabled && walletAddress) {
3294
+ const address = await ensureEncryptionReady();
3295
+ if (address) {
3296
+ const signMsg = getSignMessageForMigration();
3297
+ const updateMemoryFn = async (id, data) => {
3298
+ const result = await updateMemoryOp(storageCtx, id, data);
3299
+ if (!result.ok) {
3300
+ throw new Error(`Failed to update memory ${id} during migration`);
3301
+ }
3302
+ };
3303
+ const decrypted = await decryptMemoriesBatch(
3304
+ storedMemories,
3305
+ address,
3306
+ signMsg,
3307
+ updateMemoryFn
3308
+ );
3309
+ setMemories(decrypted);
3310
+ return;
3311
+ }
3312
+ }
3004
3313
  setMemories(storedMemories);
3005
- }, [storageCtx]);
3314
+ }, [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]);
3006
3315
  const extractMemoriesFromMessage = useCallback3(
3007
3316
  async (opts) => {
3008
3317
  const { messages, model } = opts;
@@ -3136,21 +3445,38 @@ function useMemoryStorage(options) {
3136
3445
  pii: item.pii
3137
3446
  })
3138
3447
  );
3139
- const savedMemories = await saveMemoriesOp(storageCtx, createOptions);
3448
+ let optionsToSave = createOptions;
3449
+ if (isEncryptionEnabled && walletAddress) {
3450
+ const address = await ensureEncryptionReady();
3451
+ if (address) {
3452
+ optionsToSave = await Promise.all(
3453
+ createOptions.map(async (opt) => {
3454
+ const encrypted = await encryptMemoryFields(
3455
+ opt,
3456
+ address
3457
+ );
3458
+ return encrypted;
3459
+ })
3460
+ );
3461
+ }
3462
+ }
3463
+ const savedMemories = await saveMemoriesOp(storageCtx, optionsToSave);
3140
3464
  console.log(
3141
3465
  `Saved ${savedMemories.length} memories to WatermelonDB`
3142
3466
  );
3143
3467
  if (generateEmbeddings && embeddingModel) {
3144
3468
  try {
3145
- for (const saved of savedMemories) {
3469
+ for (let i = 0; i < savedMemories.length; i++) {
3470
+ const memory = createOptions[i];
3471
+ const saved = savedMemories[i];
3146
3472
  const memoryItem = {
3147
- type: saved.type,
3148
- namespace: saved.namespace,
3149
- key: saved.key,
3150
- value: saved.value,
3151
- rawEvidence: saved.rawEvidence,
3152
- confidence: saved.confidence,
3153
- pii: saved.pii
3473
+ type: memory.type,
3474
+ namespace: memory.namespace,
3475
+ key: memory.key,
3476
+ value: memory.value,
3477
+ rawEvidence: memory.rawEvidence,
3478
+ confidence: memory.confidence,
3479
+ pii: memory.pii
3154
3480
  };
3155
3481
  const embedding = await generateEmbeddingForMemory(
3156
3482
  memoryItem,
@@ -3171,6 +3497,19 @@ function useMemoryStorage(options) {
3171
3497
  }
3172
3498
  }
3173
3499
  await refreshMemories();
3500
+ if (isEncryptionEnabled && walletAddress && !encryptionLockRef.current) {
3501
+ const address = await ensureEncryptionReady();
3502
+ if (address) {
3503
+ const encryptionPromise = encryptUnencryptedMemories(address).catch((err) => {
3504
+ if (process.env.NODE_ENV === "development") {
3505
+ console.error("Failed to encrypt memories:", err);
3506
+ }
3507
+ }).finally(() => {
3508
+ encryptionLockRef.current = null;
3509
+ });
3510
+ encryptionLockRef.current = encryptionPromise;
3511
+ }
3512
+ }
3174
3513
  } catch (error) {
3175
3514
  console.error("Failed to save memories to WatermelonDB:", error);
3176
3515
  }
@@ -3195,7 +3534,11 @@ function useMemoryStorage(options) {
3195
3534
  onFactsExtracted,
3196
3535
  baseUrl,
3197
3536
  storageCtx,
3198
- refreshMemories
3537
+ refreshMemories,
3538
+ isEncryptionEnabled,
3539
+ walletAddress,
3540
+ ensureEncryptionReady,
3541
+ encryptUnencryptedMemories
3199
3542
  ]
3200
3543
  );
3201
3544
  const searchMemories = useCallback3(
@@ -3215,6 +3558,25 @@ function useMemoryStorage(options) {
3215
3558
  limit,
3216
3559
  minSimilarity
3217
3560
  );
3561
+ if (isEncryptionEnabled && walletAddress && results.length > 0) {
3562
+ const address = await ensureEncryptionReady();
3563
+ if (address) {
3564
+ const signMsg = getSignMessageForMigration();
3565
+ const updateMemoryFn = async (id, data) => {
3566
+ const result = await updateMemoryOp(storageCtx, id, data);
3567
+ if (!result.ok) {
3568
+ throw new Error(`Failed to update memory ${id} during migration`);
3569
+ }
3570
+ };
3571
+ const decrypted = await decryptMemoriesBatch(
3572
+ results,
3573
+ address,
3574
+ signMsg,
3575
+ updateMemoryFn
3576
+ );
3577
+ return decrypted;
3578
+ }
3579
+ }
3218
3580
  if (results.length === 0) {
3219
3581
  console.warn(
3220
3582
  `[Memory Search] No memories found above similarity threshold ${minSimilarity}.`
@@ -3229,31 +3591,71 @@ function useMemoryStorage(options) {
3229
3591
  return [];
3230
3592
  }
3231
3593
  },
3232
- [embeddingModel, embeddingOptions, storageCtx]
3594
+ [embeddingModel, embeddingOptions, storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
3233
3595
  );
3234
3596
  const fetchAllMemories = useCallback3(async () => {
3235
3597
  try {
3236
- return await getAllMemoriesOp(storageCtx);
3598
+ const memories2 = await getAllMemoriesOp(storageCtx);
3599
+ if (isEncryptionEnabled && walletAddress && memories2.length > 0) {
3600
+ const address = await ensureEncryptionReady();
3601
+ if (address) {
3602
+ const signMsg = getSignMessageForMigration();
3603
+ const updateMemoryFn = async (id, data) => {
3604
+ const result = await updateMemoryOp(storageCtx, id, data);
3605
+ if (!result.ok) {
3606
+ throw new Error(`Failed to update memory ${id} during migration`);
3607
+ }
3608
+ };
3609
+ const decrypted = await decryptMemoriesBatch(
3610
+ memories2,
3611
+ address,
3612
+ signMsg,
3613
+ updateMemoryFn
3614
+ );
3615
+ return decrypted;
3616
+ }
3617
+ }
3618
+ return memories2;
3237
3619
  } catch (error) {
3238
3620
  throw new Error(
3239
3621
  "Failed to fetch all memories: " + (error instanceof Error ? error.message : String(error))
3240
3622
  );
3241
3623
  }
3242
- }, [storageCtx]);
3624
+ }, [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]);
3243
3625
  const fetchMemoriesByNamespace = useCallback3(
3244
3626
  async (namespace) => {
3245
3627
  if (!namespace) {
3246
3628
  throw new Error("Missing required field: namespace");
3247
3629
  }
3248
3630
  try {
3249
- return await getMemoriesByNamespaceOp(storageCtx, namespace);
3631
+ const memories2 = await getMemoriesByNamespaceOp(storageCtx, namespace);
3632
+ if (isEncryptionEnabled && walletAddress && memories2.length > 0) {
3633
+ const address = await ensureEncryptionReady();
3634
+ if (address) {
3635
+ const signMsg = getSignMessageForMigration();
3636
+ const updateMemoryFn = async (id, data) => {
3637
+ const result = await updateMemoryOp(storageCtx, id, data);
3638
+ if (!result.ok) {
3639
+ throw new Error(`Failed to update memory ${id} during migration`);
3640
+ }
3641
+ };
3642
+ const decrypted = await decryptMemoriesBatch(
3643
+ memories2,
3644
+ address,
3645
+ signMsg,
3646
+ updateMemoryFn
3647
+ );
3648
+ return decrypted;
3649
+ }
3650
+ }
3651
+ return memories2;
3250
3652
  } catch (error) {
3251
3653
  throw new Error(
3252
3654
  `Failed to fetch memories for namespace "${namespace}": ` + (error instanceof Error ? error.message : String(error))
3253
3655
  );
3254
3656
  }
3255
3657
  },
3256
- [storageCtx]
3658
+ [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
3257
3659
  );
3258
3660
  const fetchMemoriesByKey = useCallback3(
3259
3661
  async (namespace, key) => {
@@ -3261,31 +3663,82 @@ function useMemoryStorage(options) {
3261
3663
  throw new Error("Missing required fields: namespace, key");
3262
3664
  }
3263
3665
  try {
3264
- return await getMemoriesByKeyOp(storageCtx, namespace, key);
3666
+ const memories2 = await getMemoriesByKeyOp(storageCtx, namespace, key);
3667
+ if (isEncryptionEnabled && walletAddress && memories2.length > 0) {
3668
+ const address = await ensureEncryptionReady();
3669
+ if (address) {
3670
+ const signMsg = getSignMessageForMigration();
3671
+ const updateMemoryFn = async (id, data) => {
3672
+ const result = await updateMemoryOp(storageCtx, id, data);
3673
+ if (!result.ok) {
3674
+ throw new Error(`Failed to update memory ${id} during migration`);
3675
+ }
3676
+ };
3677
+ const decrypted = await decryptMemoriesBatch(
3678
+ memories2,
3679
+ address,
3680
+ signMsg,
3681
+ updateMemoryFn
3682
+ );
3683
+ return decrypted;
3684
+ }
3685
+ }
3686
+ return memories2;
3265
3687
  } catch (error) {
3266
3688
  throw new Error(
3267
3689
  `Failed to fetch memories for "${namespace}:${key}": ` + (error instanceof Error ? error.message : String(error))
3268
3690
  );
3269
3691
  }
3270
3692
  },
3271
- [storageCtx]
3693
+ [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
3272
3694
  );
3273
3695
  const getMemoryById = useCallback3(
3274
3696
  async (id) => {
3275
3697
  try {
3276
- return await getMemoryByIdOp(storageCtx, id);
3698
+ const memory = await getMemoryByIdOp(storageCtx, id);
3699
+ if (!memory) return null;
3700
+ if (isEncryptionEnabled && walletAddress) {
3701
+ const address = await ensureEncryptionReady();
3702
+ if (address) {
3703
+ const signMsg = getSignMessageForMigration();
3704
+ const updateMemoryFn = async (id2, data) => {
3705
+ const result = await updateMemoryOp(storageCtx, id2, data);
3706
+ if (!result.ok) {
3707
+ throw new Error(`Failed to update memory ${id2} during migration`);
3708
+ }
3709
+ };
3710
+ const decrypted = await decryptMemoryFields(
3711
+ memory,
3712
+ address,
3713
+ signMsg,
3714
+ updateMemoryFn
3715
+ );
3716
+ return decrypted;
3717
+ }
3718
+ }
3719
+ return memory;
3277
3720
  } catch (error) {
3278
3721
  throw new Error(
3279
3722
  `Failed to get memory ${id}: ` + (error instanceof Error ? error.message : String(error))
3280
3723
  );
3281
3724
  }
3282
3725
  },
3283
- [storageCtx]
3726
+ [storageCtx, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
3284
3727
  );
3285
3728
  const saveMemory = useCallback3(
3286
3729
  async (memory) => {
3287
3730
  try {
3288
- const saved = await saveMemoryOp(storageCtx, memory);
3731
+ let memoryToSave = memory;
3732
+ if (isEncryptionEnabled && walletAddress) {
3733
+ const address = await ensureEncryptionReady();
3734
+ if (address) {
3735
+ memoryToSave = await encryptMemoryFields(
3736
+ memory,
3737
+ address
3738
+ );
3739
+ }
3740
+ }
3741
+ const saved = await saveMemoryOp(storageCtx, memoryToSave);
3289
3742
  if (generateEmbeddings && embeddingModel && !memory.embedding) {
3290
3743
  try {
3291
3744
  const memoryItem = {
@@ -3311,26 +3764,60 @@ function useMemoryStorage(options) {
3311
3764
  console.error("Failed to generate embedding:", error);
3312
3765
  }
3313
3766
  }
3767
+ let savedForState = saved;
3768
+ if (isEncryptionEnabled && walletAddress) {
3769
+ const address = await ensureEncryptionReady();
3770
+ if (address) {
3771
+ const signMsg = getSignMessageForMigration();
3772
+ const updateMemoryFn = async (id, data) => {
3773
+ const result = await updateMemoryOp(storageCtx, id, data);
3774
+ if (!result.ok) {
3775
+ throw new Error(`Failed to update memory ${id} during migration`);
3776
+ }
3777
+ };
3778
+ savedForState = await decryptMemoryFields(
3779
+ saved,
3780
+ address,
3781
+ signMsg,
3782
+ updateMemoryFn
3783
+ );
3784
+ }
3785
+ }
3314
3786
  setMemories((prev) => {
3315
- const existing = prev.find((m) => m.uniqueId === saved.uniqueId);
3787
+ const existing = prev.find((m) => m.uniqueId === savedForState.uniqueId);
3316
3788
  if (existing) {
3317
- return prev.map((m) => m.uniqueId === saved.uniqueId ? saved : m);
3789
+ return prev.map((m) => m.uniqueId === savedForState.uniqueId ? savedForState : m);
3318
3790
  }
3319
- return [saved, ...prev];
3791
+ return [savedForState, ...prev];
3320
3792
  });
3321
- return saved;
3793
+ return savedForState;
3322
3794
  } catch (error) {
3323
3795
  throw new Error(
3324
3796
  "Failed to save memory: " + (error instanceof Error ? error.message : String(error))
3325
3797
  );
3326
3798
  }
3327
3799
  },
3328
- [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions]
3800
+ [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
3329
3801
  );
3330
3802
  const saveMemories = useCallback3(
3331
3803
  async (memoriesToSave) => {
3332
3804
  try {
3333
- const saved = await saveMemoriesOp(storageCtx, memoriesToSave);
3805
+ let optionsToSave = memoriesToSave;
3806
+ if (isEncryptionEnabled && walletAddress) {
3807
+ const address = await ensureEncryptionReady();
3808
+ if (address) {
3809
+ optionsToSave = await Promise.all(
3810
+ memoriesToSave.map(async (opt) => {
3811
+ const encrypted = await encryptMemoryFields(
3812
+ opt,
3813
+ address
3814
+ );
3815
+ return encrypted;
3816
+ })
3817
+ );
3818
+ }
3819
+ }
3820
+ const saved = await saveMemoriesOp(storageCtx, optionsToSave);
3334
3821
  if (generateEmbeddings && embeddingModel) {
3335
3822
  for (let i = 0; i < saved.length; i++) {
3336
3823
  const memory = memoriesToSave[i];
@@ -3361,8 +3848,27 @@ function useMemoryStorage(options) {
3361
3848
  }
3362
3849
  }
3363
3850
  }
3851
+ let savedForReturn = saved;
3852
+ if (isEncryptionEnabled && walletAddress) {
3853
+ const address = await ensureEncryptionReady();
3854
+ if (address) {
3855
+ const signMsg = getSignMessageForMigration();
3856
+ const updateMemoryFn = async (id, data) => {
3857
+ const result = await updateMemoryOp(storageCtx, id, data);
3858
+ if (!result.ok) {
3859
+ throw new Error(`Failed to update memory ${id} during migration`);
3860
+ }
3861
+ };
3862
+ savedForReturn = await decryptMemoriesBatch(
3863
+ saved,
3864
+ address,
3865
+ signMsg,
3866
+ updateMemoryFn
3867
+ );
3868
+ }
3869
+ }
3364
3870
  await refreshMemories();
3365
- return saved;
3871
+ return savedForReturn;
3366
3872
  } catch (error) {
3367
3873
  throw new Error(
3368
3874
  "Failed to save memories: " + (error instanceof Error ? error.message : String(error))
@@ -3374,12 +3880,56 @@ function useMemoryStorage(options) {
3374
3880
  generateEmbeddings,
3375
3881
  embeddingModel,
3376
3882
  embeddingOptions,
3377
- refreshMemories
3883
+ refreshMemories,
3884
+ isEncryptionEnabled,
3885
+ walletAddress,
3886
+ ensureEncryptionReady,
3887
+ getSignMessageForMigration
3378
3888
  ]
3379
3889
  );
3380
3890
  const updateMemory = useCallback3(
3381
3891
  async (id, updates) => {
3382
- const result = await updateMemoryOp(storageCtx, id, updates);
3892
+ let updatesToSave = updates;
3893
+ if (isEncryptionEnabled && walletAddress) {
3894
+ const address = await ensureEncryptionReady();
3895
+ if (address) {
3896
+ try {
3897
+ const fieldsToEncrypt = {};
3898
+ if (updates.value !== void 0) {
3899
+ fieldsToEncrypt.value = updates.value;
3900
+ }
3901
+ if (updates.rawEvidence !== void 0) {
3902
+ fieldsToEncrypt.rawEvidence = updates.rawEvidence;
3903
+ }
3904
+ if (updates.key !== void 0) {
3905
+ fieldsToEncrypt.key = updates.key;
3906
+ }
3907
+ if (updates.namespace !== void 0) {
3908
+ fieldsToEncrypt.namespace = updates.namespace;
3909
+ }
3910
+ const encrypted = await encryptMemoryFields(fieldsToEncrypt, address);
3911
+ const encryptedUpdates = { ...updates };
3912
+ if (updates.value !== void 0) {
3913
+ encryptedUpdates.value = encrypted.value;
3914
+ }
3915
+ if (updates.rawEvidence !== void 0) {
3916
+ encryptedUpdates.rawEvidence = encrypted.rawEvidence;
3917
+ }
3918
+ if (updates.key !== void 0) {
3919
+ encryptedUpdates.key = encrypted.key;
3920
+ }
3921
+ if (updates.namespace !== void 0) {
3922
+ encryptedUpdates.namespace = encrypted.namespace;
3923
+ }
3924
+ updatesToSave = encryptedUpdates;
3925
+ } catch (error) {
3926
+ throw new Error(
3927
+ `Failed to encrypt memory fields: ${error instanceof Error ? error.message : "Unknown error"}`
3928
+ );
3929
+ }
3930
+ }
3931
+ }
3932
+ const result = await updateMemoryOp(storageCtx, id, updatesToSave);
3383
3933
  if (!result.ok) {
3384
3934
  if (result.reason === "not_found") {
3385
3935
  return null;
@@ -3393,7 +3943,25 @@ function useMemoryStorage(options) {
3393
3943
  `Failed to update memory ${id}: ${result.error.message}`
3394
3944
  );
3395
3945
  }
3396
- const updated = result.memory;
3946
+ let updated = result.memory;
3947
+ if (isEncryptionEnabled && walletAddress) {
3948
+ const address = await ensureEncryptionReady();
3949
+ if (address) {
3950
+ const signMsg = getSignMessageForMigration();
3951
+ const updateMemoryFn = async (id2, data) => {
3952
+ const result2 = await updateMemoryOp(storageCtx, id2, data);
3953
+ if (!result2.ok) {
3954
+ throw new Error(`Failed to update memory ${id2} during migration`);
3955
+ }
3956
+ };
3957
+ updated = await decryptMemoryFields(
3958
+ updated,
3959
+ address,
3960
+ signMsg,
3961
+ updateMemoryFn
3962
+ );
3963
+ }
3964
+ }
3397
3965
  const contentChanged = updates.value !== void 0 || updates.rawEvidence !== void 0 || updates.type !== void 0 || updates.namespace !== void 0 || updates.key !== void 0;
3398
3966
  if (contentChanged && generateEmbeddings && embeddingModel && !updates.embedding) {
3399
3967
  try {
@@ -3425,7 +3993,7 @@ function useMemoryStorage(options) {
3425
3993
  );
3426
3994
  return updated;
3427
3995
  },
3428
- [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions]
3996
+ [storageCtx, generateEmbeddings, embeddingModel, embeddingOptions, isEncryptionEnabled, walletAddress, ensureEncryptionReady, getSignMessageForMigration]
3429
3997
  );
3430
3998
  const removeMemory = useCallback3(
3431
3999
  async (namespace, key, value) => {
@@ -3510,7 +4078,7 @@ function useMemoryStorage(options) {
3510
4078
  }
3511
4079
 
3512
4080
  // src/react/useSettings.ts
3513
- import { useCallback as useCallback4, useState as useState4, useMemo as useMemo3, useEffect as useEffect2 } from "react";
4081
+ import { useCallback as useCallback4, useState as useState4, useMemo as useMemo3, useEffect as useEffect3 } from "react";
3514
4082
 
3515
4083
  // src/lib/db/settings/schema.ts
3516
4084
  import { appSchema as appSchema4, tableSchema as tableSchema4 } from "@nozbe/watermelondb";
@@ -3632,7 +4200,7 @@ function useSettings(options) {
3632
4200
  },
3633
4201
  [storageCtx, walletAddress]
3634
4202
  );
3635
- useEffect2(() => {
4203
+ useEffect3(() => {
3636
4204
  if (!walletAddress) {
3637
4205
  setModelPreferenceState(null);
3638
4206
  return;
@@ -3859,7 +4427,7 @@ ${text4}`;
3859
4427
  }
3860
4428
 
3861
4429
  // src/react/useModels.ts
3862
- import { useCallback as useCallback7, useEffect as useEffect3, useRef as useRef3, useState as useState7 } from "react";
4430
+ import { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef3, useState as useState7 } from "react";
3863
4431
  function useModels(options = {}) {
3864
4432
  const { getToken, baseUrl = BASE_URL, provider, autoFetch = true } = options;
3865
4433
  const [models, setModels] = useState7([]);
@@ -3869,12 +4437,12 @@ function useModels(options = {}) {
3869
4437
  const baseUrlRef = useRef3(baseUrl);
3870
4438
  const providerRef = useRef3(provider);
3871
4439
  const abortControllerRef = useRef3(null);
3872
- useEffect3(() => {
4440
+ useEffect4(() => {
3873
4441
  getTokenRef.current = getToken;
3874
4442
  baseUrlRef.current = baseUrl;
3875
4443
  providerRef.current = provider;
3876
4444
  });
3877
- useEffect3(() => {
4445
+ useEffect4(() => {
3878
4446
  return () => {
3879
4447
  if (abortControllerRef.current) {
3880
4448
  abortControllerRef.current.abort();
@@ -3945,7 +4513,7 @@ function useModels(options = {}) {
3945
4513
  await fetchModels();
3946
4514
  }, [fetchModels]);
3947
4515
  const hasFetchedRef = useRef3(false);
3948
- useEffect3(() => {
4516
+ useEffect4(() => {
3949
4517
  if (autoFetch && !hasFetchedRef.current) {
3950
4518
  hasFetchedRef.current = true;
3951
4519
  fetchModels();
@@ -3963,7 +4531,7 @@ function useModels(options = {}) {
3963
4531
  }
3964
4532
 
3965
4533
  // src/react/useSearch.ts
3966
- import { useCallback as useCallback8, useEffect as useEffect4, useRef as useRef4, useState as useState8 } from "react";
4534
+ import { useCallback as useCallback8, useEffect as useEffect5, useRef as useRef4, useState as useState8 } from "react";
3967
4535
  function useSearch(options = {}) {
3968
4536
  const { getToken, baseUrl = BASE_URL, onError } = options;
3969
4537
  const [isLoading, setIsLoading] = useState8(false);
@@ -3971,7 +4539,7 @@ function useSearch(options = {}) {
3971
4539
  const [response, setResponse] = useState8(null);
3972
4540
  const [error, setError] = useState8(null);
3973
4541
  const abortControllerRef = useRef4(null);
3974
- useEffect4(() => {
4542
+ useEffect5(() => {
3975
4543
  return () => {
3976
4544
  if (abortControllerRef.current) {
3977
4545
  abortControllerRef.current.abort();
@@ -4047,12 +4615,12 @@ function useSearch(options = {}) {
4047
4615
  }
4048
4616
 
4049
4617
  // src/react/useImageGeneration.ts
4050
- import { useCallback as useCallback9, useEffect as useEffect5, useRef as useRef5, useState as useState9 } from "react";
4618
+ import { useCallback as useCallback9, useEffect as useEffect6, useRef as useRef5, useState as useState9 } from "react";
4051
4619
  function useImageGeneration(options = {}) {
4052
4620
  const { getToken, baseUrl = BASE_URL, onFinish, onError } = options;
4053
4621
  const [isLoading, setIsLoading] = useState9(false);
4054
4622
  const abortControllerRef = useRef5(null);
4055
- useEffect5(() => {
4623
+ useEffect6(() => {
4056
4624
  return () => {
4057
4625
  if (abortControllerRef.current) {
4058
4626
  abortControllerRef.current.abort();
@@ -4434,66 +5002,10 @@ import {
4434
5002
  createElement,
4435
5003
  useCallback as useCallback10,
4436
5004
  useContext,
4437
- useEffect as useEffect6,
5005
+ useEffect as useEffect7,
4438
5006
  useState as useState10
4439
5007
  } from "react";
4440
5008
 
4441
- // src/lib/backup/oauth/storage.ts
4442
- var STORAGE_KEY_PREFIX = "oauth_token_";
4443
- function getStorageKey(provider) {
4444
- return `${STORAGE_KEY_PREFIX}${provider}`;
4445
- }
4446
- function getStoredTokenData(provider) {
4447
- if (typeof window === "undefined") return null;
4448
- try {
4449
- const stored = localStorage.getItem(getStorageKey(provider));
4450
- if (!stored) return null;
4451
- const data = JSON.parse(stored);
4452
- if (!data.accessToken) return null;
4453
- return data;
4454
- } catch {
4455
- return null;
4456
- }
4457
- }
4458
- function storeTokenData(provider, data) {
4459
- if (typeof window === "undefined") return;
4460
- localStorage.setItem(getStorageKey(provider), JSON.stringify(data));
4461
- }
4462
- function clearTokenData(provider) {
4463
- if (typeof window === "undefined") return;
4464
- localStorage.removeItem(getStorageKey(provider));
4465
- }
4466
- function isTokenExpired(data, bufferSeconds = 60) {
4467
- if (!data) return true;
4468
- if (!data.expiresAt) return false;
4469
- const now = Date.now();
4470
- const bufferMs = bufferSeconds * 1e3;
4471
- return data.expiresAt - bufferMs <= now;
4472
- }
4473
- function getValidAccessToken(provider) {
4474
- const data = getStoredTokenData(provider);
4475
- if (!data) return null;
4476
- if (data.expiresAt && isTokenExpired(data)) {
4477
- return null;
4478
- }
4479
- return data.accessToken;
4480
- }
4481
- function getRefreshToken(provider) {
4482
- const data = getStoredTokenData(provider);
4483
- return data?.refreshToken ?? null;
4484
- }
4485
- function tokenResponseToStoredData(accessToken, expiresIn, refreshToken, scope) {
4486
- const data = {
4487
- accessToken,
4488
- refreshToken,
4489
- scope
4490
- };
4491
- if (expiresIn) {
4492
- data.expiresAt = Date.now() + expiresIn * 1e3;
4493
- }
4494
- return data;
4495
- }
4496
-
4497
5009
  // src/lib/backup/dropbox/auth.ts
4498
5010
  var PROVIDER = "dropbox";
4499
5011
  var STATE_STORAGE_KEY = "dropbox_oauth_state";
@@ -4502,6 +5014,7 @@ function getRedirectUri(callbackPath) {
4502
5014
  if (typeof window === "undefined") return "";
4503
5015
  return `${window.location.origin}${callbackPath}`;
4504
5016
  }
5017
+ var MAX_STATE_AGE_MS = 10 * 60 * 1e3;
4505
5018
  function generateState() {
4506
5019
  const array = new Uint8Array(16);
4507
5020
  crypto.getRandomValues(array);
@@ -4511,21 +5024,48 @@ function generateState() {
4511
5024
  }
4512
5025
  function storeOAuthState(state) {
4513
5026
  if (typeof window === "undefined") return;
4514
- sessionStorage.setItem(STATE_STORAGE_KEY, state);
5027
+ const stateData = {
5028
+ state,
5029
+ timestamp: Date.now()
5030
+ };
5031
+ sessionStorage.setItem(STATE_STORAGE_KEY, JSON.stringify(stateData));
4515
5032
  }
4516
5033
  function getAndClearOAuthState() {
4517
5034
  if (typeof window === "undefined") return null;
4518
- const state = sessionStorage.getItem(STATE_STORAGE_KEY);
4519
- sessionStorage.removeItem(STATE_STORAGE_KEY);
4520
- return state;
5035
+ try {
5036
+ const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
5037
+ if (!stored) return null;
5038
+ const stateData = JSON.parse(stored);
5039
+ const age = Date.now() - stateData.timestamp;
5040
+ if (age > MAX_STATE_AGE_MS) {
5041
+ sessionStorage.removeItem(STATE_STORAGE_KEY);
5042
+ return null;
5043
+ }
5044
+ sessionStorage.removeItem(STATE_STORAGE_KEY);
5045
+ return stateData.state;
5046
+ } catch {
5047
+ sessionStorage.removeItem(STATE_STORAGE_KEY);
5048
+ return null;
5049
+ }
4521
5050
  }
4522
5051
  function isDropboxCallback() {
4523
5052
  if (typeof window === "undefined") return false;
4524
5053
  const url = new URL(window.location.href);
4525
5054
  const code = url.searchParams.get("code");
4526
5055
  const state = url.searchParams.get("state");
4527
- const storedState = sessionStorage.getItem(STATE_STORAGE_KEY);
4528
- return !!code && !!state && state === storedState;
5056
+ if (!code || !state) return false;
5057
+ try {
5058
+ const stored = sessionStorage.getItem(STATE_STORAGE_KEY);
5059
+ if (!stored) return false;
5060
+ const stateData = JSON.parse(stored);
5061
+ const age = Date.now() - stateData.timestamp;
5062
+ if (age > MAX_STATE_AGE_MS) {
5063
+ return false;
5064
+ }
5065
+ return state === stateData.state;
5066
+ } catch {
5067
+ return false;
5068
+ }
4529
5069
  }
4530
5070
  async function handleDropboxCallback(callbackPath, apiClient) {
4531
5071
  if (typeof window === "undefined") return null;
@@ -4554,15 +5094,35 @@ async function handleDropboxCallback(callbackPath, apiClient) {
4554
5094
  response.data.refresh_token,
4555
5095
  response.data.scope
4556
5096
  );
4557
- storeTokenData(PROVIDER, tokenData);
5097
+ try {
5098
+ await storeTokenData(PROVIDER, tokenData);
5099
+ } catch (error) {
5100
+ const errorMessage = error instanceof Error ? error.message : "Unknown encryption error";
5101
+ console.error("OAuth token encryption failed in Dropbox callback:", errorMessage);
5102
+ console.warn("OAuth token encryption failed - tokens not stored securely");
5103
+ return null;
5104
+ }
4558
5105
  window.history.replaceState({}, "", window.location.pathname);
4559
5106
  return response.data.access_token;
4560
- } catch {
5107
+ } catch (error) {
5108
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
5109
+ const errorName = error instanceof Error ? error.name : "Error";
5110
+ console.error(`Dropbox OAuth callback error: ${errorName}: ${errorMessage}`);
5111
+ console.error("Error details:", {
5112
+ name: errorName,
5113
+ message: errorMessage,
5114
+ stack: error instanceof Error ? error.stack : void 0
5115
+ });
5116
+ console.warn(`Dropbox OAuth callback failed: ${errorMessage}`);
5117
+ if (errorMessage.includes("encryption failed") || errorMessage.includes("OAuth token encryption")) {
5118
+ console.warn("OAuth callback failed due to encryption error - this is a security issue");
5119
+ throw error;
5120
+ }
4561
5121
  return null;
4562
5122
  }
4563
5123
  }
4564
- async function refreshDropboxToken(apiClient) {
4565
- const refreshToken = getRefreshToken(PROVIDER);
5124
+ async function refreshDropboxToken(apiClient, walletAddress) {
5125
+ const refreshToken = walletAddress ? await getRefreshToken(PROVIDER, walletAddress) : getRefreshTokenSync(PROVIDER);
4566
5126
  if (!refreshToken) return null;
4567
5127
  try {
4568
5128
  const response = await postAuthOauthByProviderRefresh({
@@ -4573,22 +5133,22 @@ async function refreshDropboxToken(apiClient) {
4573
5133
  if (!response.data?.access_token) {
4574
5134
  throw new Error("No access token in refresh response");
4575
5135
  }
4576
- const currentData = getStoredTokenData(PROVIDER);
5136
+ const currentData = walletAddress ? await getStoredTokenData(PROVIDER, walletAddress) : getStoredTokenDataSync(PROVIDER);
4577
5137
  const tokenData = tokenResponseToStoredData(
4578
5138
  response.data.access_token,
4579
5139
  response.data.expires_in,
4580
5140
  response.data.refresh_token ?? currentData?.refreshToken,
4581
5141
  response.data.scope ?? currentData?.scope
4582
5142
  );
4583
- storeTokenData(PROVIDER, tokenData);
5143
+ await storeTokenData(PROVIDER, tokenData, walletAddress);
4584
5144
  return response.data.access_token;
4585
5145
  } catch {
4586
5146
  clearTokenData(PROVIDER);
4587
5147
  return null;
4588
5148
  }
4589
5149
  }
4590
- async function revokeDropboxToken(apiClient) {
4591
- const tokenData = getStoredTokenData(PROVIDER);
5150
+ async function revokeDropboxToken(apiClient, walletAddress) {
5151
+ const tokenData = walletAddress ? await getStoredTokenData(PROVIDER, walletAddress) : getStoredTokenDataSync(PROVIDER);
4592
5152
  if (!tokenData) return;
4593
5153
  try {
4594
5154
  const tokenToRevoke = tokenData.refreshToken ?? tokenData.accessToken;
@@ -4602,10 +5162,10 @@ async function revokeDropboxToken(apiClient) {
4602
5162
  clearTokenData(PROVIDER);
4603
5163
  }
4604
5164
  }
4605
- async function getDropboxAccessToken(apiClient) {
4606
- const validToken = getValidAccessToken(PROVIDER);
5165
+ async function getDropboxAccessToken(apiClient, walletAddress) {
5166
+ const validToken = walletAddress ? await getValidAccessToken(PROVIDER, walletAddress) : getValidAccessTokenSync(PROVIDER);
4607
5167
  if (validToken) return validToken;
4608
- return refreshDropboxToken(apiClient);
5168
+ return refreshDropboxToken(apiClient, walletAddress);
4609
5169
  }
4610
5170
  async function startDropboxAuth(appKey, callbackPath) {
4611
5171
  const state = generateState();
@@ -4626,8 +5186,7 @@ function clearToken() {
4626
5186
  clearTokenData(PROVIDER);
4627
5187
  }
4628
5188
  function hasDropboxCredentials() {
4629
- const data = getStoredTokenData(PROVIDER);
4630
- return !!(data?.accessToken || data?.refreshToken);
5189
+ return hasStoredCredentialsSync(PROVIDER);
4631
5190
  }
4632
5191
 
4633
5192
  // src/react/useDropboxAuth.ts
@@ -4640,7 +5199,7 @@ function DropboxAuthProvider({
4640
5199
  }) {
4641
5200
  const [accessToken, setAccessToken] = useState10(null);
4642
5201
  const isConfigured = !!appKey;
4643
- useEffect6(() => {
5202
+ useEffect7(() => {
4644
5203
  const checkStoredToken = async () => {
4645
5204
  if (hasDropboxCredentials()) {
4646
5205
  const token = await getDropboxAccessToken(apiClient);
@@ -4651,7 +5210,7 @@ function DropboxAuthProvider({
4651
5210
  };
4652
5211
  checkStoredToken();
4653
5212
  }, [apiClient]);
4654
- useEffect6(() => {
5213
+ useEffect7(() => {
4655
5214
  if (!isConfigured) return;
4656
5215
  const handleCallback = async () => {
4657
5216
  if (isDropboxCallback()) {
@@ -4808,7 +5367,7 @@ import {
4808
5367
  createElement as createElement2,
4809
5368
  useCallback as useCallback12,
4810
5369
  useContext as useContext2,
4811
- useEffect as useEffect7,
5370
+ useEffect as useEffect8,
4812
5371
  useState as useState11
4813
5372
  } from "react";
4814
5373
 
@@ -4824,6 +5383,7 @@ function getRedirectUri2(callbackPath) {
4824
5383
  if (typeof window === "undefined") return "";
4825
5384
  return `${window.location.origin}${callbackPath}`;
4826
5385
  }
5386
+ var MAX_STATE_AGE_MS2 = 10 * 60 * 1e3;
4827
5387
  function generateState2() {
4828
5388
  const array = new Uint8Array(16);
4829
5389
  crypto.getRandomValues(array);
@@ -4833,21 +5393,48 @@ function generateState2() {
4833
5393
  }
4834
5394
  function storeOAuthState2(state) {
4835
5395
  if (typeof window === "undefined") return;
4836
- sessionStorage.setItem(CODE_STORAGE_KEY, state);
5396
+ const stateData = {
5397
+ state,
5398
+ timestamp: Date.now()
5399
+ };
5400
+ sessionStorage.setItem(CODE_STORAGE_KEY, JSON.stringify(stateData));
4837
5401
  }
4838
5402
  function getAndClearOAuthState2() {
4839
5403
  if (typeof window === "undefined") return null;
4840
- const state = sessionStorage.getItem(CODE_STORAGE_KEY);
4841
- sessionStorage.removeItem(CODE_STORAGE_KEY);
4842
- return state;
5404
+ try {
5405
+ const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
5406
+ if (!stored) return null;
5407
+ const stateData = JSON.parse(stored);
5408
+ const age = Date.now() - stateData.timestamp;
5409
+ if (age > MAX_STATE_AGE_MS2) {
5410
+ sessionStorage.removeItem(CODE_STORAGE_KEY);
5411
+ return null;
5412
+ }
5413
+ sessionStorage.removeItem(CODE_STORAGE_KEY);
5414
+ return stateData.state;
5415
+ } catch {
5416
+ sessionStorage.removeItem(CODE_STORAGE_KEY);
5417
+ return null;
5418
+ }
4843
5419
  }
4844
5420
  function isGoogleDriveCallback() {
4845
5421
  if (typeof window === "undefined") return false;
4846
5422
  const url = new URL(window.location.href);
4847
5423
  const code = url.searchParams.get("code");
4848
5424
  const state = url.searchParams.get("state");
4849
- const storedState = sessionStorage.getItem(CODE_STORAGE_KEY);
4850
- return !!code && !!state && state === storedState;
5425
+ if (!code || !state) return false;
5426
+ try {
5427
+ const stored = sessionStorage.getItem(CODE_STORAGE_KEY);
5428
+ if (!stored) return false;
5429
+ const stateData = JSON.parse(stored);
5430
+ const age = Date.now() - stateData.timestamp;
5431
+ if (age > MAX_STATE_AGE_MS2) {
5432
+ return false;
5433
+ }
5434
+ return state === stateData.state;
5435
+ } catch {
5436
+ return false;
5437
+ }
4851
5438
  }
4852
5439
  async function handleGoogleDriveCallback(callbackPath, apiClient) {
4853
5440
  if (typeof window === "undefined") return null;
@@ -4876,15 +5463,35 @@ async function handleGoogleDriveCallback(callbackPath, apiClient) {
4876
5463
  response.data.refresh_token,
4877
5464
  response.data.scope
4878
5465
  );
4879
- storeTokenData(PROVIDER2, tokenData);
5466
+ try {
5467
+ await storeTokenData(PROVIDER2, tokenData);
5468
+ } catch (error) {
5469
+ const errorMessage = error instanceof Error ? error.message : "Unknown encryption error";
5470
+ console.error("OAuth token encryption failed in Google Drive callback:", errorMessage);
5471
+ console.warn("OAuth token encryption failed - tokens not stored securely");
5472
+ return null;
5473
+ }
4880
5474
  window.history.replaceState({}, "", window.location.pathname);
4881
5475
  return response.data.access_token;
4882
- } catch {
5476
+ } catch (error) {
5477
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
5478
+ const errorName = error instanceof Error ? error.name : "Error";
5479
+ console.error(`Google Drive OAuth callback error: ${errorName}: ${errorMessage}`);
5480
+ console.error("Error details:", {
5481
+ name: errorName,
5482
+ message: errorMessage,
5483
+ stack: error instanceof Error ? error.stack : void 0
5484
+ });
5485
+ console.warn(`Google Drive OAuth callback failed: ${errorMessage}`);
5486
+ if (errorMessage.includes("encryption failed") || errorMessage.includes("OAuth token encryption")) {
5487
+ console.warn("OAuth callback failed due to encryption error - this is a security issue");
5488
+ throw error;
5489
+ }
4883
5490
  return null;
4884
5491
  }
4885
5492
  }
4886
- async function refreshGoogleDriveToken(apiClient) {
4887
- const refreshToken = getRefreshToken(PROVIDER2);
5493
+ async function refreshGoogleDriveToken(apiClient, walletAddress) {
5494
+ const refreshToken = walletAddress ? await getRefreshToken(PROVIDER2, walletAddress) : getRefreshTokenSync(PROVIDER2);
4888
5495
  if (!refreshToken) return null;
4889
5496
  try {
4890
5497
  const response = await postAuthOauthByProviderRefresh({
@@ -4895,22 +5502,22 @@ async function refreshGoogleDriveToken(apiClient) {
4895
5502
  if (!response.data?.access_token) {
4896
5503
  throw new Error("No access token in refresh response");
4897
5504
  }
4898
- const currentData = getStoredTokenData(PROVIDER2);
5505
+ const currentData = walletAddress ? await getStoredTokenData(PROVIDER2, walletAddress) : getStoredTokenDataSync(PROVIDER2);
4899
5506
  const tokenData = tokenResponseToStoredData(
4900
5507
  response.data.access_token,
4901
5508
  response.data.expires_in,
4902
5509
  response.data.refresh_token ?? currentData?.refreshToken,
4903
5510
  response.data.scope ?? currentData?.scope
4904
5511
  );
4905
- storeTokenData(PROVIDER2, tokenData);
5512
+ await storeTokenData(PROVIDER2, tokenData, walletAddress);
4906
5513
  return response.data.access_token;
4907
5514
  } catch {
4908
5515
  clearTokenData(PROVIDER2);
4909
5516
  return null;
4910
5517
  }
4911
5518
  }
4912
- async function revokeGoogleDriveToken(apiClient) {
4913
- const tokenData = getStoredTokenData(PROVIDER2);
5519
+ async function revokeGoogleDriveToken(apiClient, walletAddress) {
5520
+ const tokenData = walletAddress ? await getStoredTokenData(PROVIDER2, walletAddress) : getStoredTokenDataSync(PROVIDER2);
4914
5521
  if (!tokenData) return;
4915
5522
  try {
4916
5523
  const tokenToRevoke = tokenData.refreshToken ?? tokenData.accessToken;
@@ -4924,8 +5531,8 @@ async function revokeGoogleDriveToken(apiClient) {
4924
5531
  clearTokenData(PROVIDER2);
4925
5532
  }
4926
5533
  }
4927
- async function getGoogleDriveAccessToken(apiClient) {
4928
- const storedData = getStoredTokenData(PROVIDER2);
5534
+ async function getGoogleDriveAccessToken(apiClient, walletAddress) {
5535
+ const storedData = walletAddress ? await getStoredTokenData(PROVIDER2, walletAddress) : getStoredTokenDataSync(PROVIDER2);
4929
5536
  if (!storedData) {
4930
5537
  return null;
4931
5538
  }
@@ -4933,7 +5540,7 @@ async function getGoogleDriveAccessToken(apiClient) {
4933
5540
  return storedData.accessToken;
4934
5541
  }
4935
5542
  if (storedData.refreshToken) {
4936
- const refreshedToken = await refreshGoogleDriveToken(apiClient);
5543
+ const refreshedToken = await refreshGoogleDriveToken(apiClient, walletAddress);
4937
5544
  if (refreshedToken) {
4938
5545
  return refreshedToken;
4939
5546
  }
@@ -4962,14 +5569,13 @@ async function startGoogleDriveAuth(clientId, callbackPath) {
4962
5569
  });
4963
5570
  }
4964
5571
  function getGoogleDriveStoredToken() {
4965
- return getValidAccessToken(PROVIDER2);
5572
+ return getValidAccessTokenSync(PROVIDER2);
4966
5573
  }
4967
5574
  function clearGoogleDriveToken() {
4968
5575
  clearTokenData(PROVIDER2);
4969
5576
  }
4970
5577
  function hasGoogleDriveCredentials() {
4971
- const data = getStoredTokenData(PROVIDER2);
4972
- return !!(data?.accessToken || data?.refreshToken);
5578
+ return hasStoredCredentialsSync(PROVIDER2);
4973
5579
  }
4974
5580
 
4975
5581
  // src/react/useGoogleDriveAuth.ts
@@ -4982,7 +5588,7 @@ function GoogleDriveAuthProvider({
4982
5588
  }) {
4983
5589
  const [accessToken, setAccessToken] = useState11(null);
4984
5590
  const isConfigured = !!clientId;
4985
- useEffect7(() => {
5591
+ useEffect8(() => {
4986
5592
  const checkStoredToken = async () => {
4987
5593
  if (hasGoogleDriveCredentials()) {
4988
5594
  const token = await getGoogleDriveAccessToken(apiClient);
@@ -4993,7 +5599,7 @@ function GoogleDriveAuthProvider({
4993
5599
  };
4994
5600
  checkStoredToken();
4995
5601
  }, [apiClient]);
4996
- useEffect7(() => {
5602
+ useEffect8(() => {
4997
5603
  if (!isConfigured) return;
4998
5604
  const handleCallback = async () => {
4999
5605
  if (isGoogleDriveCallback()) {
@@ -5458,7 +6064,7 @@ import {
5458
6064
  createElement as createElement3,
5459
6065
  useCallback as useCallback14,
5460
6066
  useContext as useContext3,
5461
- useEffect as useEffect8,
6067
+ useEffect as useEffect9,
5462
6068
  useState as useState12
5463
6069
  } from "react";
5464
6070
 
@@ -5708,7 +6314,7 @@ function ICloudAuthProvider({
5708
6314
  const [isAvailable, setIsAvailable] = useState12(false);
5709
6315
  const [isConfigured, setIsConfigured] = useState12(false);
5710
6316
  const [isLoading, setIsLoading] = useState12(false);
5711
- useEffect8(() => {
6317
+ useEffect9(() => {
5712
6318
  if (!apiToken || typeof window === "undefined") {
5713
6319
  return;
5714
6320
  }
@@ -6024,7 +6630,7 @@ import {
6024
6630
  createElement as createElement4,
6025
6631
  useCallback as useCallback16,
6026
6632
  useContext as useContext4,
6027
- useEffect as useEffect9,
6633
+ useEffect as useEffect10,
6028
6634
  useState as useState13
6029
6635
  } from "react";
6030
6636
  var BackupAuthContext = createContext4(null);
@@ -6047,7 +6653,7 @@ function BackupAuthProvider({
6047
6653
  const [icloudUserRecordName, setIcloudUserRecordName] = useState13(null);
6048
6654
  const [isIcloudAvailable, setIsIcloudAvailable] = useState13(false);
6049
6655
  const isIcloudConfigured = isIcloudAvailable && !!icloudApiToken;
6050
- useEffect9(() => {
6656
+ useEffect10(() => {
6051
6657
  const checkStoredTokens = async () => {
6052
6658
  if (hasDropboxCredentials()) {
6053
6659
  const token = await getDropboxAccessToken(apiClient);
@@ -6064,7 +6670,7 @@ function BackupAuthProvider({
6064
6670
  };
6065
6671
  checkStoredTokens();
6066
6672
  }, [apiClient]);
6067
- useEffect9(() => {
6673
+ useEffect10(() => {
6068
6674
  if (!icloudApiToken || typeof window === "undefined") {
6069
6675
  return;
6070
6676
  }
@@ -6092,7 +6698,7 @@ function BackupAuthProvider({
6092
6698
  };
6093
6699
  initCloudKit();
6094
6700
  }, [icloudApiToken, icloudContainerIdentifier, icloudEnvironment]);
6095
- useEffect9(() => {
6701
+ useEffect10(() => {
6096
6702
  if (!isDropboxConfigured) return;
6097
6703
  const handleCallback = async () => {
6098
6704
  if (isDropboxCallback()) {
@@ -6107,7 +6713,7 @@ function BackupAuthProvider({
6107
6713
  };
6108
6714
  handleCallback();
6109
6715
  }, [dropboxCallbackPath, isDropboxConfigured, apiClient]);
6110
- useEffect9(() => {
6716
+ useEffect10(() => {
6111
6717
  if (!isGoogleConfigured) return;
6112
6718
  const handleCallback = async () => {
6113
6719
  if (isGoogleDriveCallback()) {
@@ -6529,6 +7135,7 @@ export {
6529
7135
  BackupAuthProvider,
6530
7136
  Conversation as ChatConversation,
6531
7137
  Message as ChatMessage,
7138
+ DECRYPTION_FAILED_PLACEHOLDER,
6532
7139
  DEFAULT_BACKUP_FOLDER,
6533
7140
  DEFAULT_CONVERSATIONS_FOLDER as DEFAULT_DRIVE_CONVERSATIONS_FOLDER,
6534
7141
  DEFAULT_ROOT_FOLDER as DEFAULT_DRIVE_ROOT_FOLDER,
@@ -6542,26 +7149,41 @@ export {
6542
7149
  chatStorageMigrations,
6543
7150
  chatStorageSchema,
6544
7151
  clearAllEncryptionKeys,
7152
+ clearAllKeyPairs,
6545
7153
  clearToken as clearDropboxToken,
6546
7154
  clearEncryptionKey,
6547
7155
  clearGoogleDriveToken,
6548
7156
  clearICloudAuth,
7157
+ clearKeyPair,
6549
7158
  createMemoryContextSystemMessage,
6550
7159
  decryptData,
6551
7160
  decryptDataBytes,
7161
+ decryptField,
7162
+ decryptMemoriesBatch,
7163
+ decryptMemoryFields,
6552
7164
  encryptData,
7165
+ encryptField,
7166
+ encryptMemoriesBatch,
7167
+ encryptMemoriesBatchInPlace,
7168
+ encryptMemoryFields,
7169
+ exportPublicKey,
6553
7170
  extractConversationContext,
6554
7171
  formatMemoriesForChat,
6555
7172
  generateCompositeKey,
6556
7173
  generateConversationId,
6557
7174
  generateUniqueKey,
7175
+ getEncryptionVersion2 as getEncryptionVersion,
6558
7176
  getGoogleDriveStoredToken,
6559
7177
  hasDropboxCredentials,
7178
+ hasEncryptedFields,
6560
7179
  hasEncryptionKey,
6561
7180
  hasGoogleDriveCredentials,
6562
7181
  hasICloudCredentials,
7182
+ hasKeyPair,
6563
7183
  memoryStorageSchema,
7184
+ needsEncryption,
6564
7185
  requestEncryptionKey,
7186
+ requestKeyPair,
6565
7187
  sdkMigrations,
6566
7188
  sdkModelClasses,
6567
7189
  sdkSchema,