@reverbia/sdk 1.0.0-next.20251125084024 → 1.0.0-next.20251125205812

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.
@@ -31,9 +31,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  createMemoryContextSystemMessage: () => createMemoryContextSystemMessage,
34
+ decryptData: () => decryptData,
35
+ decryptDataBytes: () => decryptDataBytes,
36
+ encryptData: () => encryptData,
34
37
  extractConversationContext: () => extractConversationContext,
35
38
  formatMemoriesForChat: () => formatMemoriesForChat,
36
39
  useChat: () => useChat,
40
+ useEncryption: () => useEncryption,
37
41
  useMemory: () => useMemory
38
42
  });
39
43
  module.exports = __toCommonJS(index_exports);
@@ -857,7 +861,13 @@ var client = createClient(createClientConfig(createConfig()));
857
861
 
858
862
  // src/react/useChat.ts
859
863
  function useChat(options) {
860
- const { getToken, onData: globalOnData, onFinish, onError } = options || {};
864
+ const {
865
+ getToken,
866
+ baseUrl,
867
+ onData: globalOnData,
868
+ onFinish,
869
+ onError
870
+ } = options || {};
861
871
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
862
872
  const abortControllerRef = (0, import_react.useRef)(null);
863
873
  const stop = (0, import_react.useCallback)(() => {
@@ -998,7 +1008,7 @@ function useChat(options) {
998
1008
  }
999
1009
  }
1000
1010
  },
1001
- [getToken, globalOnData, onFinish, onError]
1011
+ [getToken, baseUrl, globalOnData, onFinish, onError]
1002
1012
  );
1003
1013
  return {
1004
1014
  isLoading,
@@ -1007,8 +1017,166 @@ function useChat(options) {
1007
1017
  };
1008
1018
  }
1009
1019
 
1010
- // src/react/useMemory.ts
1020
+ // src/react/useEncryption.ts
1011
1021
  var import_react2 = require("react");
1022
+ var import_react_auth = require("@privy-io/react-auth");
1023
+ var SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
1024
+ var SIGNATURE_STORAGE_KEY = "privy_encryption_key";
1025
+ function getStorageItem(key) {
1026
+ if (typeof window === "undefined" || !window.localStorage) {
1027
+ return null;
1028
+ }
1029
+ try {
1030
+ return localStorage.getItem(key);
1031
+ } catch {
1032
+ return null;
1033
+ }
1034
+ }
1035
+ function setStorageItem(key, value) {
1036
+ if (typeof window === "undefined" || !window.localStorage) {
1037
+ return false;
1038
+ }
1039
+ try {
1040
+ localStorage.setItem(key, value);
1041
+ return true;
1042
+ } catch {
1043
+ return false;
1044
+ }
1045
+ }
1046
+ function hexToBytes(hex) {
1047
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
1048
+ const bytes = new Uint8Array(cleanHex.length / 2);
1049
+ for (let i = 0; i < cleanHex.length; i += 2) {
1050
+ bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
1051
+ }
1052
+ return bytes;
1053
+ }
1054
+ function bytesToHex(bytes) {
1055
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1056
+ }
1057
+ async function deriveKeyFromSignature(signature) {
1058
+ const sigBytes = hexToBytes(signature);
1059
+ const hashBuffer = await crypto.subtle.digest(
1060
+ "SHA-256",
1061
+ sigBytes.buffer
1062
+ );
1063
+ const hashBytes = new Uint8Array(hashBuffer);
1064
+ return bytesToHex(hashBytes);
1065
+ }
1066
+ async function getEncryptionKey() {
1067
+ const keyHex = getStorageItem(SIGNATURE_STORAGE_KEY);
1068
+ if (!keyHex) {
1069
+ throw new Error("Encryption key not found. Please sign in first.");
1070
+ }
1071
+ const keyBytes = hexToBytes(keyHex);
1072
+ return crypto.subtle.importKey(
1073
+ "raw",
1074
+ keyBytes.buffer,
1075
+ { name: "AES-GCM" },
1076
+ false,
1077
+ ["encrypt", "decrypt"]
1078
+ );
1079
+ }
1080
+ async function encryptData(plaintext) {
1081
+ const key = await getEncryptionKey();
1082
+ const plaintextBytes = typeof plaintext === "string" ? new TextEncoder().encode(plaintext) : plaintext;
1083
+ const iv = crypto.getRandomValues(new Uint8Array(12));
1084
+ const encryptedData = await crypto.subtle.encrypt(
1085
+ {
1086
+ name: "AES-GCM",
1087
+ iv
1088
+ },
1089
+ key,
1090
+ plaintextBytes.buffer
1091
+ );
1092
+ const encryptedBytes = new Uint8Array(encryptedData);
1093
+ const combined = new Uint8Array(iv.length + encryptedBytes.length);
1094
+ combined.set(iv, 0);
1095
+ combined.set(encryptedBytes, iv.length);
1096
+ return bytesToHex(combined);
1097
+ }
1098
+ async function decryptData(encryptedHex) {
1099
+ const key = await getEncryptionKey();
1100
+ const combined = hexToBytes(encryptedHex);
1101
+ const iv = combined.slice(0, 12);
1102
+ const encryptedData = combined.slice(12);
1103
+ const decryptedData = await crypto.subtle.decrypt(
1104
+ {
1105
+ name: "AES-GCM",
1106
+ iv
1107
+ },
1108
+ key,
1109
+ encryptedData
1110
+ );
1111
+ return new TextDecoder().decode(decryptedData);
1112
+ }
1113
+ async function decryptDataBytes(encryptedHex) {
1114
+ const key = await getEncryptionKey();
1115
+ const combined = hexToBytes(encryptedHex);
1116
+ const iv = combined.slice(0, 12);
1117
+ const encryptedData = combined.slice(12);
1118
+ const decryptedData = await crypto.subtle.decrypt(
1119
+ {
1120
+ name: "AES-GCM",
1121
+ iv
1122
+ },
1123
+ key,
1124
+ encryptedData
1125
+ );
1126
+ return new Uint8Array(decryptedData);
1127
+ }
1128
+ function useEncryption(authenticated) {
1129
+ const { signMessage } = (0, import_react_auth.useSignMessage)();
1130
+ const { wallets } = (0, import_react_auth.useWallets)();
1131
+ const hasRequestedSignature = (0, import_react2.useRef)(false);
1132
+ const hasCheckedStorage = (0, import_react2.useRef)(false);
1133
+ (0, import_react2.useEffect)(() => {
1134
+ if (!authenticated || wallets.length === 0) {
1135
+ return;
1136
+ }
1137
+ const existingKey = getStorageItem(SIGNATURE_STORAGE_KEY);
1138
+ if (existingKey) {
1139
+ if (!hasCheckedStorage.current) {
1140
+ hasCheckedStorage.current = true;
1141
+ }
1142
+ return;
1143
+ }
1144
+ const requestSignature = async () => {
1145
+ if (!hasRequestedSignature.current) {
1146
+ hasRequestedSignature.current = true;
1147
+ try {
1148
+ const { signature } = await signMessage(
1149
+ { message: SIGN_MESSAGE },
1150
+ {
1151
+ address: wallets[0].address
1152
+ }
1153
+ );
1154
+ const encryptionKey = await deriveKeyFromSignature(signature);
1155
+ const stored = setStorageItem(SIGNATURE_STORAGE_KEY, encryptionKey);
1156
+ if (!stored) {
1157
+ throw new Error("Failed to store encryption key in localStorage");
1158
+ }
1159
+ } catch (error) {
1160
+ hasRequestedSignature.current = false;
1161
+ }
1162
+ }
1163
+ };
1164
+ requestSignature();
1165
+ }, [
1166
+ authenticated,
1167
+ wallets.length > 0 ? wallets[0]?.address : null,
1168
+ signMessage
1169
+ ]);
1170
+ (0, import_react2.useEffect)(() => {
1171
+ if (!authenticated) {
1172
+ hasRequestedSignature.current = false;
1173
+ hasCheckedStorage.current = false;
1174
+ }
1175
+ }, [authenticated]);
1176
+ }
1177
+
1178
+ // src/react/useMemory.ts
1179
+ var import_react3 = require("react");
1012
1180
  var import_client6 = require("@reverbia/sdk");
1013
1181
 
1014
1182
  // src/lib/memory/service.ts
@@ -1239,7 +1407,11 @@ var postApiV1Embeddings = (options) => {
1239
1407
 
1240
1408
  // src/lib/memory/embeddings.ts
1241
1409
  var generateEmbeddingForText = async (text, options = {}) => {
1242
- const { model = "openai/text-embedding-3-small", getToken } = options;
1410
+ const {
1411
+ model = "openai/text-embedding-3-small",
1412
+ getToken,
1413
+ baseUrl
1414
+ } = options;
1243
1415
  try {
1244
1416
  const token = getToken ? await getToken() : null;
1245
1417
  const headers = {};
@@ -1247,6 +1419,7 @@ var generateEmbeddingForText = async (text, options = {}) => {
1247
1419
  headers.Authorization = `Bearer ${token}`;
1248
1420
  }
1249
1421
  const response = await postApiV1Embeddings({
1422
+ baseUrl,
1250
1423
  body: {
1251
1424
  input: text,
1252
1425
  model
@@ -1279,14 +1452,19 @@ var generateEmbeddingForMemory = async (memory, options = {}) => {
1279
1452
  return generateEmbeddingForText(text, options);
1280
1453
  };
1281
1454
  var generateEmbeddingsForMemories = async (memories, options = {}) => {
1282
- const { model = "openai/text-embedding-3-small", getToken } = options;
1455
+ const {
1456
+ model = "openai/text-embedding-3-small",
1457
+ getToken,
1458
+ baseUrl
1459
+ } = options;
1283
1460
  const embeddings = /* @__PURE__ */ new Map();
1284
1461
  for (const memory of memories) {
1285
1462
  const uniqueKey = `${memory.namespace}:${memory.key}:${memory.value}`;
1286
1463
  try {
1287
1464
  const embedding = await generateEmbeddingForMemory(memory, {
1288
1465
  model,
1289
- getToken
1466
+ getToken,
1467
+ baseUrl
1290
1468
  });
1291
1469
  embeddings.set(uniqueKey, embedding);
1292
1470
  } catch (error) {
@@ -1339,10 +1517,11 @@ function useMemory(options = {}) {
1339
1517
  embeddingModel = "openai/text-embedding-3-small",
1340
1518
  generateEmbeddings = true,
1341
1519
  onFactsExtracted,
1342
- getToken
1520
+ getToken,
1521
+ baseUrl
1343
1522
  } = options;
1344
- const extractionInProgressRef = (0, import_react2.useRef)(false);
1345
- const extractMemoriesFromMessage = (0, import_react2.useCallback)(
1523
+ const extractionInProgressRef = (0, import_react3.useRef)(false);
1524
+ const extractMemoriesFromMessage = (0, import_react3.useCallback)(
1346
1525
  async (options2) => {
1347
1526
  const { messages, model } = options2;
1348
1527
  if (!getToken || extractionInProgressRef.current) {
@@ -1356,6 +1535,7 @@ function useMemory(options = {}) {
1356
1535
  return null;
1357
1536
  }
1358
1537
  const completion = await (0, import_client6.postApiV1ChatCompletions)({
1538
+ baseUrl,
1359
1539
  body: {
1360
1540
  messages: [
1361
1541
  {
@@ -1479,7 +1659,8 @@ function useMemory(options = {}) {
1479
1659
  try {
1480
1660
  await generateAndStoreEmbeddings(result.items, {
1481
1661
  model: embeddingModel,
1482
- getToken: getToken || void 0
1662
+ getToken: getToken || void 0,
1663
+ baseUrl
1483
1664
  });
1484
1665
  console.log(
1485
1666
  `Generated embeddings for ${result.items.length} memories`
@@ -1508,10 +1689,11 @@ function useMemory(options = {}) {
1508
1689
  embeddingModel,
1509
1690
  generateEmbeddings,
1510
1691
  getToken,
1511
- onFactsExtracted
1692
+ onFactsExtracted,
1693
+ baseUrl
1512
1694
  ]
1513
1695
  );
1514
- const searchMemories = (0, import_react2.useCallback)(
1696
+ const searchMemories = (0, import_react3.useCallback)(
1515
1697
  async (query, limit = 10, minSimilarity = 0.6) => {
1516
1698
  if (!getToken || !embeddingModel) {
1517
1699
  console.warn(
@@ -1523,7 +1705,8 @@ function useMemory(options = {}) {
1523
1705
  console.log(`[Memory Search] Searching for: "${query}"`);
1524
1706
  const queryEmbedding = await generateQueryEmbedding(query, {
1525
1707
  model: embeddingModel,
1526
- getToken
1708
+ getToken,
1709
+ baseUrl
1527
1710
  });
1528
1711
  console.log(
1529
1712
  `[Memory Search] Generated query embedding (${queryEmbedding.length} dimensions)`
@@ -1548,7 +1731,7 @@ function useMemory(options = {}) {
1548
1731
  return [];
1549
1732
  }
1550
1733
  },
1551
- [embeddingModel, getToken]
1734
+ [embeddingModel, getToken, baseUrl]
1552
1735
  );
1553
1736
  return {
1554
1737
  extractMemoriesFromMessage,
@@ -1613,8 +1796,12 @@ var extractConversationContext = (messages, maxMessages = 3) => {
1613
1796
  // Annotate the CommonJS export names for ESM import in node:
1614
1797
  0 && (module.exports = {
1615
1798
  createMemoryContextSystemMessage,
1799
+ decryptData,
1800
+ decryptDataBytes,
1801
+ encryptData,
1616
1802
  extractConversationContext,
1617
1803
  formatMemoriesForChat,
1618
1804
  useChat,
1805
+ useEncryption,
1619
1806
  useMemory
1620
1807
  });
@@ -98,6 +98,7 @@ type SendMessageResult = {
98
98
  };
99
99
  type UseChatOptions = {
100
100
  getToken?: () => Promise<string | null>;
101
+ baseUrl?: string;
101
102
  /**
102
103
  * Callback function to be called when a new data chunk is received.
103
104
  */
@@ -141,6 +142,7 @@ type UseChatResult = {
141
142
  * @param options.getToken - An async function that returns an authentication token.
142
143
  * This token will be used as a Bearer token in the Authorization header.
143
144
  * If not provided, `sendMessage` will return an error.
145
+ * @param options.baseUrl - Optional base URL for the API requests.
144
146
  * @param options.onData - Callback function to be called when a new data chunk is received.
145
147
  * @param options.onFinish - Callback function to be called when the chat completion finishes successfully.
146
148
  * @param options.onError - Callback function to be called when an unexpected error
@@ -190,6 +192,26 @@ type UseChatResult = {
190
192
  */
191
193
  declare function useChat(options?: UseChatOptions): UseChatResult;
192
194
 
195
+ /**
196
+ * Encrypts data using AES-GCM with the stored encryption key
197
+ * @param plaintext - The data to encrypt (string or Uint8Array)
198
+ * @returns Encrypted data as hex string (IV + ciphertext + auth tag)
199
+ */
200
+ declare function encryptData(plaintext: string | Uint8Array): Promise<string>;
201
+ /**
202
+ * Decrypts data using AES-GCM with the stored encryption key
203
+ * @param encryptedHex - Encrypted data as hex string (IV + ciphertext + auth tag)
204
+ * @returns Decrypted data as string
205
+ */
206
+ declare function decryptData(encryptedHex: string): Promise<string>;
207
+ /**
208
+ * Decrypts data and returns as Uint8Array (for binary data)
209
+ * @param encryptedHex - Encrypted data as hex string (IV + ciphertext + auth tag)
210
+ * @returns Decrypted data as Uint8Array
211
+ */
212
+ declare function decryptDataBytes(encryptedHex: string): Promise<Uint8Array>;
213
+ declare function useEncryption(authenticated: boolean): void;
214
+
193
215
  interface MemoryItem {
194
216
  type: "identity" | "preference" | "project" | "skill" | "constraint";
195
217
  namespace: string;
@@ -238,6 +260,10 @@ type UseMemoryOptions = {
238
260
  * Custom function to get auth token for API calls
239
261
  */
240
262
  getToken?: () => Promise<string | null>;
263
+ /**
264
+ * Optional base URL for the API requests.
265
+ */
266
+ baseUrl?: string;
241
267
  };
242
268
  type UseMemoryResult = {
243
269
  extractMemoriesFromMessage: (options: {
@@ -295,4 +321,4 @@ declare const extractConversationContext: (messages: Array<{
295
321
  content: string;
296
322
  }>, maxMessages?: number) => string;
297
323
 
298
- export { createMemoryContextSystemMessage, extractConversationContext, formatMemoriesForChat, useChat, useMemory };
324
+ export { createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, extractConversationContext, formatMemoriesForChat, useChat, useEncryption, useMemory };
@@ -98,6 +98,7 @@ type SendMessageResult = {
98
98
  };
99
99
  type UseChatOptions = {
100
100
  getToken?: () => Promise<string | null>;
101
+ baseUrl?: string;
101
102
  /**
102
103
  * Callback function to be called when a new data chunk is received.
103
104
  */
@@ -141,6 +142,7 @@ type UseChatResult = {
141
142
  * @param options.getToken - An async function that returns an authentication token.
142
143
  * This token will be used as a Bearer token in the Authorization header.
143
144
  * If not provided, `sendMessage` will return an error.
145
+ * @param options.baseUrl - Optional base URL for the API requests.
144
146
  * @param options.onData - Callback function to be called when a new data chunk is received.
145
147
  * @param options.onFinish - Callback function to be called when the chat completion finishes successfully.
146
148
  * @param options.onError - Callback function to be called when an unexpected error
@@ -190,6 +192,26 @@ type UseChatResult = {
190
192
  */
191
193
  declare function useChat(options?: UseChatOptions): UseChatResult;
192
194
 
195
+ /**
196
+ * Encrypts data using AES-GCM with the stored encryption key
197
+ * @param plaintext - The data to encrypt (string or Uint8Array)
198
+ * @returns Encrypted data as hex string (IV + ciphertext + auth tag)
199
+ */
200
+ declare function encryptData(plaintext: string | Uint8Array): Promise<string>;
201
+ /**
202
+ * Decrypts data using AES-GCM with the stored encryption key
203
+ * @param encryptedHex - Encrypted data as hex string (IV + ciphertext + auth tag)
204
+ * @returns Decrypted data as string
205
+ */
206
+ declare function decryptData(encryptedHex: string): Promise<string>;
207
+ /**
208
+ * Decrypts data and returns as Uint8Array (for binary data)
209
+ * @param encryptedHex - Encrypted data as hex string (IV + ciphertext + auth tag)
210
+ * @returns Decrypted data as Uint8Array
211
+ */
212
+ declare function decryptDataBytes(encryptedHex: string): Promise<Uint8Array>;
213
+ declare function useEncryption(authenticated: boolean): void;
214
+
193
215
  interface MemoryItem {
194
216
  type: "identity" | "preference" | "project" | "skill" | "constraint";
195
217
  namespace: string;
@@ -238,6 +260,10 @@ type UseMemoryOptions = {
238
260
  * Custom function to get auth token for API calls
239
261
  */
240
262
  getToken?: () => Promise<string | null>;
263
+ /**
264
+ * Optional base URL for the API requests.
265
+ */
266
+ baseUrl?: string;
241
267
  };
242
268
  type UseMemoryResult = {
243
269
  extractMemoriesFromMessage: (options: {
@@ -295,4 +321,4 @@ declare const extractConversationContext: (messages: Array<{
295
321
  content: string;
296
322
  }>, maxMessages?: number) => string;
297
323
 
298
- export { createMemoryContextSystemMessage, extractConversationContext, formatMemoriesForChat, useChat, useMemory };
324
+ export { createMemoryContextSystemMessage, decryptData, decryptDataBytes, encryptData, extractConversationContext, formatMemoriesForChat, useChat, useEncryption, useMemory };
@@ -817,7 +817,13 @@ var client = createClient(createClientConfig(createConfig()));
817
817
 
818
818
  // src/react/useChat.ts
819
819
  function useChat(options) {
820
- const { getToken, onData: globalOnData, onFinish, onError } = options || {};
820
+ const {
821
+ getToken,
822
+ baseUrl,
823
+ onData: globalOnData,
824
+ onFinish,
825
+ onError
826
+ } = options || {};
821
827
  const [isLoading, setIsLoading] = useState(false);
822
828
  const abortControllerRef = useRef(null);
823
829
  const stop = useCallback(() => {
@@ -958,7 +964,7 @@ function useChat(options) {
958
964
  }
959
965
  }
960
966
  },
961
- [getToken, globalOnData, onFinish, onError]
967
+ [getToken, baseUrl, globalOnData, onFinish, onError]
962
968
  );
963
969
  return {
964
970
  isLoading,
@@ -967,8 +973,166 @@ function useChat(options) {
967
973
  };
968
974
  }
969
975
 
976
+ // src/react/useEncryption.ts
977
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
978
+ import { useSignMessage, useWallets } from "@privy-io/react-auth";
979
+ var SIGN_MESSAGE = "The app is asking you to sign this message to generate a key, which will be used to encrypt data.";
980
+ var SIGNATURE_STORAGE_KEY = "privy_encryption_key";
981
+ function getStorageItem(key) {
982
+ if (typeof window === "undefined" || !window.localStorage) {
983
+ return null;
984
+ }
985
+ try {
986
+ return localStorage.getItem(key);
987
+ } catch {
988
+ return null;
989
+ }
990
+ }
991
+ function setStorageItem(key, value) {
992
+ if (typeof window === "undefined" || !window.localStorage) {
993
+ return false;
994
+ }
995
+ try {
996
+ localStorage.setItem(key, value);
997
+ return true;
998
+ } catch {
999
+ return false;
1000
+ }
1001
+ }
1002
+ function hexToBytes(hex) {
1003
+ const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
1004
+ const bytes = new Uint8Array(cleanHex.length / 2);
1005
+ for (let i = 0; i < cleanHex.length; i += 2) {
1006
+ bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
1007
+ }
1008
+ return bytes;
1009
+ }
1010
+ function bytesToHex(bytes) {
1011
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1012
+ }
1013
+ async function deriveKeyFromSignature(signature) {
1014
+ const sigBytes = hexToBytes(signature);
1015
+ const hashBuffer = await crypto.subtle.digest(
1016
+ "SHA-256",
1017
+ sigBytes.buffer
1018
+ );
1019
+ const hashBytes = new Uint8Array(hashBuffer);
1020
+ return bytesToHex(hashBytes);
1021
+ }
1022
+ async function getEncryptionKey() {
1023
+ const keyHex = getStorageItem(SIGNATURE_STORAGE_KEY);
1024
+ if (!keyHex) {
1025
+ throw new Error("Encryption key not found. Please sign in first.");
1026
+ }
1027
+ const keyBytes = hexToBytes(keyHex);
1028
+ return crypto.subtle.importKey(
1029
+ "raw",
1030
+ keyBytes.buffer,
1031
+ { name: "AES-GCM" },
1032
+ false,
1033
+ ["encrypt", "decrypt"]
1034
+ );
1035
+ }
1036
+ async function encryptData(plaintext) {
1037
+ const key = await getEncryptionKey();
1038
+ const plaintextBytes = typeof plaintext === "string" ? new TextEncoder().encode(plaintext) : plaintext;
1039
+ const iv = crypto.getRandomValues(new Uint8Array(12));
1040
+ const encryptedData = await crypto.subtle.encrypt(
1041
+ {
1042
+ name: "AES-GCM",
1043
+ iv
1044
+ },
1045
+ key,
1046
+ plaintextBytes.buffer
1047
+ );
1048
+ const encryptedBytes = new Uint8Array(encryptedData);
1049
+ const combined = new Uint8Array(iv.length + encryptedBytes.length);
1050
+ combined.set(iv, 0);
1051
+ combined.set(encryptedBytes, iv.length);
1052
+ return bytesToHex(combined);
1053
+ }
1054
+ async function decryptData(encryptedHex) {
1055
+ const key = await getEncryptionKey();
1056
+ const combined = hexToBytes(encryptedHex);
1057
+ const iv = combined.slice(0, 12);
1058
+ const encryptedData = combined.slice(12);
1059
+ const decryptedData = await crypto.subtle.decrypt(
1060
+ {
1061
+ name: "AES-GCM",
1062
+ iv
1063
+ },
1064
+ key,
1065
+ encryptedData
1066
+ );
1067
+ return new TextDecoder().decode(decryptedData);
1068
+ }
1069
+ async function decryptDataBytes(encryptedHex) {
1070
+ const key = await getEncryptionKey();
1071
+ const combined = hexToBytes(encryptedHex);
1072
+ const iv = combined.slice(0, 12);
1073
+ const encryptedData = combined.slice(12);
1074
+ const decryptedData = await crypto.subtle.decrypt(
1075
+ {
1076
+ name: "AES-GCM",
1077
+ iv
1078
+ },
1079
+ key,
1080
+ encryptedData
1081
+ );
1082
+ return new Uint8Array(decryptedData);
1083
+ }
1084
+ function useEncryption(authenticated) {
1085
+ const { signMessage } = useSignMessage();
1086
+ const { wallets } = useWallets();
1087
+ const hasRequestedSignature = useRef2(false);
1088
+ const hasCheckedStorage = useRef2(false);
1089
+ useEffect2(() => {
1090
+ if (!authenticated || wallets.length === 0) {
1091
+ return;
1092
+ }
1093
+ const existingKey = getStorageItem(SIGNATURE_STORAGE_KEY);
1094
+ if (existingKey) {
1095
+ if (!hasCheckedStorage.current) {
1096
+ hasCheckedStorage.current = true;
1097
+ }
1098
+ return;
1099
+ }
1100
+ const requestSignature = async () => {
1101
+ if (!hasRequestedSignature.current) {
1102
+ hasRequestedSignature.current = true;
1103
+ try {
1104
+ const { signature } = await signMessage(
1105
+ { message: SIGN_MESSAGE },
1106
+ {
1107
+ address: wallets[0].address
1108
+ }
1109
+ );
1110
+ const encryptionKey = await deriveKeyFromSignature(signature);
1111
+ const stored = setStorageItem(SIGNATURE_STORAGE_KEY, encryptionKey);
1112
+ if (!stored) {
1113
+ throw new Error("Failed to store encryption key in localStorage");
1114
+ }
1115
+ } catch (error) {
1116
+ hasRequestedSignature.current = false;
1117
+ }
1118
+ }
1119
+ };
1120
+ requestSignature();
1121
+ }, [
1122
+ authenticated,
1123
+ wallets.length > 0 ? wallets[0]?.address : null,
1124
+ signMessage
1125
+ ]);
1126
+ useEffect2(() => {
1127
+ if (!authenticated) {
1128
+ hasRequestedSignature.current = false;
1129
+ hasCheckedStorage.current = false;
1130
+ }
1131
+ }, [authenticated]);
1132
+ }
1133
+
970
1134
  // src/react/useMemory.ts
971
- import { useCallback as useCallback2, useRef as useRef2 } from "react";
1135
+ import { useCallback as useCallback2, useRef as useRef3 } from "react";
972
1136
  import { postApiV1ChatCompletions } from "@reverbia/sdk";
973
1137
 
974
1138
  // src/lib/memory/service.ts
@@ -1199,7 +1363,11 @@ var postApiV1Embeddings = (options) => {
1199
1363
 
1200
1364
  // src/lib/memory/embeddings.ts
1201
1365
  var generateEmbeddingForText = async (text, options = {}) => {
1202
- const { model = "openai/text-embedding-3-small", getToken } = options;
1366
+ const {
1367
+ model = "openai/text-embedding-3-small",
1368
+ getToken,
1369
+ baseUrl
1370
+ } = options;
1203
1371
  try {
1204
1372
  const token = getToken ? await getToken() : null;
1205
1373
  const headers = {};
@@ -1207,6 +1375,7 @@ var generateEmbeddingForText = async (text, options = {}) => {
1207
1375
  headers.Authorization = `Bearer ${token}`;
1208
1376
  }
1209
1377
  const response = await postApiV1Embeddings({
1378
+ baseUrl,
1210
1379
  body: {
1211
1380
  input: text,
1212
1381
  model
@@ -1239,14 +1408,19 @@ var generateEmbeddingForMemory = async (memory, options = {}) => {
1239
1408
  return generateEmbeddingForText(text, options);
1240
1409
  };
1241
1410
  var generateEmbeddingsForMemories = async (memories, options = {}) => {
1242
- const { model = "openai/text-embedding-3-small", getToken } = options;
1411
+ const {
1412
+ model = "openai/text-embedding-3-small",
1413
+ getToken,
1414
+ baseUrl
1415
+ } = options;
1243
1416
  const embeddings = /* @__PURE__ */ new Map();
1244
1417
  for (const memory of memories) {
1245
1418
  const uniqueKey = `${memory.namespace}:${memory.key}:${memory.value}`;
1246
1419
  try {
1247
1420
  const embedding = await generateEmbeddingForMemory(memory, {
1248
1421
  model,
1249
- getToken
1422
+ getToken,
1423
+ baseUrl
1250
1424
  });
1251
1425
  embeddings.set(uniqueKey, embedding);
1252
1426
  } catch (error) {
@@ -1299,9 +1473,10 @@ function useMemory(options = {}) {
1299
1473
  embeddingModel = "openai/text-embedding-3-small",
1300
1474
  generateEmbeddings = true,
1301
1475
  onFactsExtracted,
1302
- getToken
1476
+ getToken,
1477
+ baseUrl
1303
1478
  } = options;
1304
- const extractionInProgressRef = useRef2(false);
1479
+ const extractionInProgressRef = useRef3(false);
1305
1480
  const extractMemoriesFromMessage = useCallback2(
1306
1481
  async (options2) => {
1307
1482
  const { messages, model } = options2;
@@ -1316,6 +1491,7 @@ function useMemory(options = {}) {
1316
1491
  return null;
1317
1492
  }
1318
1493
  const completion = await postApiV1ChatCompletions({
1494
+ baseUrl,
1319
1495
  body: {
1320
1496
  messages: [
1321
1497
  {
@@ -1439,7 +1615,8 @@ function useMemory(options = {}) {
1439
1615
  try {
1440
1616
  await generateAndStoreEmbeddings(result.items, {
1441
1617
  model: embeddingModel,
1442
- getToken: getToken || void 0
1618
+ getToken: getToken || void 0,
1619
+ baseUrl
1443
1620
  });
1444
1621
  console.log(
1445
1622
  `Generated embeddings for ${result.items.length} memories`
@@ -1468,7 +1645,8 @@ function useMemory(options = {}) {
1468
1645
  embeddingModel,
1469
1646
  generateEmbeddings,
1470
1647
  getToken,
1471
- onFactsExtracted
1648
+ onFactsExtracted,
1649
+ baseUrl
1472
1650
  ]
1473
1651
  );
1474
1652
  const searchMemories = useCallback2(
@@ -1483,7 +1661,8 @@ function useMemory(options = {}) {
1483
1661
  console.log(`[Memory Search] Searching for: "${query}"`);
1484
1662
  const queryEmbedding = await generateQueryEmbedding(query, {
1485
1663
  model: embeddingModel,
1486
- getToken
1664
+ getToken,
1665
+ baseUrl
1487
1666
  });
1488
1667
  console.log(
1489
1668
  `[Memory Search] Generated query embedding (${queryEmbedding.length} dimensions)`
@@ -1508,7 +1687,7 @@ function useMemory(options = {}) {
1508
1687
  return [];
1509
1688
  }
1510
1689
  },
1511
- [embeddingModel, getToken]
1690
+ [embeddingModel, getToken, baseUrl]
1512
1691
  );
1513
1692
  return {
1514
1693
  extractMemoriesFromMessage,
@@ -1572,8 +1751,12 @@ var extractConversationContext = (messages, maxMessages = 3) => {
1572
1751
  };
1573
1752
  export {
1574
1753
  createMemoryContextSystemMessage,
1754
+ decryptData,
1755
+ decryptDataBytes,
1756
+ encryptData,
1575
1757
  extractConversationContext,
1576
1758
  formatMemoriesForChat,
1577
1759
  useChat,
1760
+ useEncryption,
1578
1761
  useMemory
1579
1762
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reverbia/sdk",
3
- "version": "1.0.0-next.20251125084024",
3
+ "version": "1.0.0-next.20251125205812",
4
4
  "description": "",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -55,6 +55,7 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@hey-api/openapi-ts": "0.87.2",
58
+ "@privy-io/react-auth": "^3.7.0",
58
59
  "@types/react": "^19.2.6",
59
60
  "tsup": "^8.5.1",
60
61
  "typedoc": "^0.28.14",
@@ -63,6 +64,7 @@
63
64
  "typescript": "^5.9.3"
64
65
  },
65
66
  "peerDependencies": {
67
+ "@privy-io/react-auth": "^3.7.0",
66
68
  "dexie": "^4.2.1",
67
69
  "react": "^18.0.0 || ^19.0.0"
68
70
  }