@cmdoss/memwal-sdk 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +547 -547
- package/BENCHMARKS.md +238 -238
- package/README.md +310 -181
- package/dist/ai-sdk/tools.d.ts +2 -2
- package/dist/ai-sdk/tools.js +2 -2
- package/dist/client/ClientMemoryManager.js +2 -2
- package/dist/client/ClientMemoryManager.js.map +1 -1
- package/dist/client/PersonalDataWallet.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.d.ts +29 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +45 -13
- package/dist/client/SimplePDWClient.js.map +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +31 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +272 -39
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
- package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js +62 -4
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
- package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
- package/dist/config/ConfigurationHelper.js +61 -61
- package/dist/config/defaults.js +2 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/graph/GraphService.js +21 -21
- package/dist/graph/GraphService.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
- package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.js +37 -15
- package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
- package/dist/infrastructure/seal/SealService.d.ts +13 -5
- package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
- package/dist/infrastructure/seal/SealService.js +36 -34
- package/dist/infrastructure/seal/SealService.js.map +1 -1
- package/dist/langchain/createPDWRAG.js +30 -30
- package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
- package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.js +44 -4
- package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
- package/dist/services/CapabilityService.d.ts.map +1 -1
- package/dist/services/CapabilityService.js +30 -14
- package/dist/services/CapabilityService.js.map +1 -1
- package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
- package/dist/services/CrossContextPermissionService.js +9 -7
- package/dist/services/CrossContextPermissionService.js.map +1 -1
- package/dist/services/EmbeddingService.d.ts +28 -1
- package/dist/services/EmbeddingService.d.ts.map +1 -1
- package/dist/services/EmbeddingService.js +54 -0
- package/dist/services/EmbeddingService.js.map +1 -1
- package/dist/services/EncryptionService.d.ts.map +1 -1
- package/dist/services/EncryptionService.js +6 -5
- package/dist/services/EncryptionService.js.map +1 -1
- package/dist/services/GeminiAIService.js +309 -309
- package/dist/services/IndexManager.d.ts +5 -1
- package/dist/services/IndexManager.d.ts.map +1 -1
- package/dist/services/IndexManager.js +17 -40
- package/dist/services/IndexManager.js.map +1 -1
- package/dist/services/QueryService.js +1 -1
- package/dist/services/QueryService.js.map +1 -1
- package/dist/services/StorageService.d.ts +11 -0
- package/dist/services/StorageService.d.ts.map +1 -1
- package/dist/services/StorageService.js +73 -10
- package/dist/services/StorageService.js.map +1 -1
- package/dist/services/TransactionService.d.ts +20 -0
- package/dist/services/TransactionService.d.ts.map +1 -1
- package/dist/services/TransactionService.js +43 -0
- package/dist/services/TransactionService.js.map +1 -1
- package/dist/services/ViewService.js +2 -2
- package/dist/services/ViewService.js.map +1 -1
- package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
- package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
- package/dist/services/storage/QuiltBatchManager.js +410 -20
- package/dist/services/storage/QuiltBatchManager.js.map +1 -1
- package/dist/services/storage/index.d.ts +1 -1
- package/dist/services/storage/index.d.ts.map +1 -1
- package/dist/services/storage/index.js.map +1 -1
- package/dist/utils/LRUCache.d.ts +106 -0
- package/dist/utils/LRUCache.d.ts.map +1 -0
- package/dist/utils/LRUCache.js +281 -0
- package/dist/utils/LRUCache.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/memoryIndexOnChain.d.ts +212 -0
- package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
- package/dist/utils/memoryIndexOnChain.js +312 -0
- package/dist/utils/memoryIndexOnChain.js.map +1 -0
- package/dist/utils/rebuildIndexNode.d.ts +29 -0
- package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
- package/dist/utils/rebuildIndexNode.js +366 -98
- package/dist/utils/rebuildIndexNode.js.map +1 -1
- package/dist/vector/HnswWasmService.d.ts +20 -5
- package/dist/vector/HnswWasmService.d.ts.map +1 -1
- package/dist/vector/HnswWasmService.js +73 -40
- package/dist/vector/HnswWasmService.js.map +1 -1
- package/dist/vector/IHnswService.d.ts +10 -1
- package/dist/vector/IHnswService.d.ts.map +1 -1
- package/dist/vector/IHnswService.js.map +1 -1
- package/dist/vector/NodeHnswService.d.ts +16 -0
- package/dist/vector/NodeHnswService.d.ts.map +1 -1
- package/dist/vector/NodeHnswService.js +84 -5
- package/dist/vector/NodeHnswService.js.map +1 -1
- package/dist/vector/createHnswService.d.ts +1 -1
- package/dist/vector/createHnswService.js +1 -1
- package/dist/vector/index.d.ts +1 -1
- package/dist/vector/index.js +1 -1
- package/package.json +157 -157
- package/src/access/PermissionService.ts +635 -635
- package/src/aggregation/AggregationService.ts +389 -389
- package/src/ai-sdk/PDWVectorStore.ts +715 -715
- package/src/ai-sdk/index.ts +65 -65
- package/src/ai-sdk/tools.ts +460 -460
- package/src/ai-sdk/types.ts +404 -404
- package/src/batch/BatchManager.ts +597 -597
- package/src/batch/BatchingService.ts +429 -429
- package/src/batch/MemoryProcessingCache.ts +492 -492
- package/src/batch/index.ts +30 -30
- package/src/browser.ts +200 -200
- package/src/client/ClientMemoryManager.ts +987 -987
- package/src/client/PersonalDataWallet.ts +345 -345
- package/src/client/SimplePDWClient.ts +1289 -1222
- package/src/client/factory.ts +154 -154
- package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
- package/src/client/namespaces/BatchNamespace.ts +356 -356
- package/src/client/namespaces/CacheNamespace.ts +123 -123
- package/src/client/namespaces/CapabilityNamespace.ts +217 -217
- package/src/client/namespaces/ClassifyNamespace.ts +169 -169
- package/src/client/namespaces/ContextNamespace.ts +297 -297
- package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
- package/src/client/namespaces/EncryptionNamespace.ts +221 -221
- package/src/client/namespaces/GraphNamespace.ts +468 -468
- package/src/client/namespaces/IndexNamespace.ts +361 -361
- package/src/client/namespaces/MemoryNamespace.ts +1422 -1135
- package/src/client/namespaces/PermissionsNamespace.ts +254 -254
- package/src/client/namespaces/PipelineNamespace.ts +220 -220
- package/src/client/namespaces/SearchNamespace.ts +1049 -1049
- package/src/client/namespaces/StorageNamespace.ts +458 -458
- package/src/client/namespaces/TxNamespace.ts +260 -260
- package/src/client/namespaces/WalletNamespace.ts +243 -243
- package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
- package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -546
- package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
- package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
- package/src/client/namespaces/consolidated/index.ts +39 -39
- package/src/client/signers/KeypairSigner.ts +108 -108
- package/src/client/signers/UnifiedSigner.ts +110 -110
- package/src/client/signers/WalletAdapterSigner.ts +159 -159
- package/src/client/signers/index.ts +26 -26
- package/src/config/ConfigurationHelper.ts +412 -412
- package/src/config/defaults.ts +51 -51
- package/src/config/index.ts +8 -8
- package/src/config/validation.ts +70 -70
- package/src/core/index.ts +14 -14
- package/src/core/interfaces/IService.ts +307 -307
- package/src/core/interfaces/index.ts +8 -8
- package/src/core/types/capability.ts +297 -297
- package/src/core/types/index.ts +870 -870
- package/src/core/types/wallet.ts +270 -270
- package/src/core/types.ts +9 -9
- package/src/core/wallet.ts +222 -222
- package/src/embedding/index.ts +19 -19
- package/src/embedding/types.ts +357 -357
- package/src/errors/index.ts +602 -602
- package/src/errors/recovery.ts +461 -461
- package/src/errors/validation.ts +567 -567
- package/src/generated/pdw/capability.ts +319 -319
- package/src/graph/GraphService.ts +887 -887
- package/src/graph/KnowledgeGraphManager.ts +728 -728
- package/src/graph/index.ts +25 -25
- package/src/index.ts +498 -474
- package/src/infrastructure/index.ts +22 -22
- package/src/infrastructure/seal/EncryptionService.ts +628 -603
- package/src/infrastructure/seal/SealService.ts +613 -615
- package/src/infrastructure/seal/index.ts +9 -9
- package/src/infrastructure/sui/BlockchainManager.ts +627 -627
- package/src/infrastructure/sui/SuiService.ts +888 -888
- package/src/infrastructure/sui/index.ts +9 -9
- package/src/infrastructure/walrus/StorageManager.ts +604 -604
- package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
- package/src/infrastructure/walrus/index.ts +9 -9
- package/src/langchain/PDWEmbeddings.ts +145 -145
- package/src/langchain/PDWVectorStore.ts +456 -456
- package/src/langchain/createPDWRAG.ts +303 -303
- package/src/langchain/index.ts +47 -47
- package/src/permissions/ConsentRepository.browser.ts +249 -249
- package/src/permissions/ConsentRepository.ts +364 -364
- package/src/pipeline/MemoryPipeline.ts +862 -862
- package/src/pipeline/PipelineManager.ts +683 -683
- package/src/pipeline/index.ts +26 -26
- package/src/retrieval/AdvancedSearchService.ts +629 -629
- package/src/retrieval/MemoryAnalyticsService.ts +711 -711
- package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
- package/src/retrieval/MemoryRetrievalService.ts +904 -830
- package/src/retrieval/index.ts +42 -42
- package/src/services/BatchService.ts +352 -352
- package/src/services/CapabilityService.ts +464 -448
- package/src/services/ClassifierService.ts +465 -465
- package/src/services/CrossContextPermissionService.ts +486 -484
- package/src/services/EmbeddingService.ts +771 -706
- package/src/services/EncryptionService.ts +712 -711
- package/src/services/GeminiAIService.ts +753 -753
- package/src/services/IndexManager.ts +977 -1004
- package/src/services/MemoryIndexService.ts +1003 -1003
- package/src/services/MemoryService.ts +369 -369
- package/src/services/QueryService.ts +890 -890
- package/src/services/StorageService.ts +1182 -1111
- package/src/services/TransactionService.ts +838 -790
- package/src/services/VectorService.ts +462 -462
- package/src/services/ViewService.ts +484 -484
- package/src/services/index.ts +25 -25
- package/src/services/storage/BlobAttributesManager.ts +333 -333
- package/src/services/storage/KnowledgeGraphManager.ts +425 -425
- package/src/services/storage/MemorySearchManager.ts +387 -387
- package/src/services/storage/QuiltBatchManager.ts +1130 -660
- package/src/services/storage/WalrusMetadataManager.ts +268 -268
- package/src/services/storage/WalrusStorageManager.ts +287 -287
- package/src/services/storage/index.ts +57 -52
- package/src/types/index.ts +13 -13
- package/src/utils/LRUCache.ts +378 -0
- package/src/utils/index.ts +76 -68
- package/src/utils/memoryIndexOnChain.ts +507 -0
- package/src/utils/rebuildIndex.ts +290 -290
- package/src/utils/rebuildIndexNode.ts +771 -424
- package/src/vector/BrowserHnswIndexService.ts +758 -758
- package/src/vector/HnswWasmService.ts +731 -679
- package/src/vector/IHnswService.ts +233 -224
- package/src/vector/NodeHnswService.ts +833 -735
- package/src/vector/VectorManager.ts +478 -478
- package/src/vector/createHnswService.ts +135 -135
- package/src/vector/index.ts +56 -56
- package/src/wallet/ContextWalletService.ts +656 -656
- package/src/wallet/MainWalletService.ts +317 -317
|
@@ -260,6 +260,7 @@ export class StorageNamespace {
|
|
|
260
260
|
* Store memory package to Walrus
|
|
261
261
|
*
|
|
262
262
|
* Higher-level method that stores a complete memory package.
|
|
263
|
+
* Automatically encrypts content if encryption is enabled in config.
|
|
263
264
|
*
|
|
264
265
|
* @param memoryPackage - Memory package to store
|
|
265
266
|
* @returns Upload result
|
|
@@ -268,12 +269,93 @@ export class StorageNamespace {
|
|
|
268
269
|
if (!this.services.storage) {
|
|
269
270
|
throw new Error('Storage service not configured.');
|
|
270
271
|
}
|
|
272
|
+
// Check if encryption is enabled
|
|
273
|
+
const encryptionEnabled = this.services.config.features?.enableEncryption ?? true;
|
|
274
|
+
let encryptedContent;
|
|
275
|
+
let encryptedEmbedding; // Option A v2: encrypted embedding
|
|
276
|
+
let encryptionType;
|
|
277
|
+
let memoryCapId;
|
|
278
|
+
let keyId;
|
|
279
|
+
console.log('🔍 Encryption check:', {
|
|
280
|
+
encryptionEnabled,
|
|
281
|
+
hasEncryptionService: !!this.services.encryption,
|
|
282
|
+
hasCapabilityService: !!this.services.capability,
|
|
283
|
+
configFeatures: this.services.config.features
|
|
284
|
+
});
|
|
285
|
+
if (encryptionEnabled && this.services.encryption && this.services.capability) {
|
|
286
|
+
console.log('🔒 Encrypting memory package with SEAL (capability-based)...');
|
|
287
|
+
try {
|
|
288
|
+
// Step 1: Get or create capability for this app context
|
|
289
|
+
const category = memoryPackage.metadata?.category || 'general';
|
|
290
|
+
console.log(`🔐 Getting/creating capability for category: ${category}`);
|
|
291
|
+
const cap = await this.services.capability.getOrCreate({
|
|
292
|
+
appId: category,
|
|
293
|
+
userAddress: this.services.config.userAddress
|
|
294
|
+
}, this.services.config.signer);
|
|
295
|
+
memoryCapId = cap.id;
|
|
296
|
+
console.log(`✅ Capability ready: ${memoryCapId}`);
|
|
297
|
+
// Step 2: Compute key_id from capability (keccak256(owner || nonce))
|
|
298
|
+
keyId = this.services.capability.computeKeyId(cap);
|
|
299
|
+
console.log(`🔑 Key ID computed: ${keyId.substring(0, 20)}...`);
|
|
300
|
+
// Step 3: Encrypt the content using key_id as SEAL identity
|
|
301
|
+
const contentBytes = new TextEncoder().encode(memoryPackage.content);
|
|
302
|
+
const encryptResult = await this.services.encryption.encrypt(contentBytes, keyId, // Use key_id from capability as SEAL identity!
|
|
303
|
+
2 // threshold: 2 of 2 key servers
|
|
304
|
+
);
|
|
305
|
+
encryptedContent = encryptResult.encryptedObject;
|
|
306
|
+
encryptionType = 'seal-capability';
|
|
307
|
+
console.log(`✅ Content encrypted: ${contentBytes.length} bytes → ${encryptedContent?.length || 0} bytes`);
|
|
308
|
+
// Step 4: Also encrypt the embedding for fast index rebuild (Option A v2)
|
|
309
|
+
const embeddingToEncrypt = memoryPackage.embedding && memoryPackage.embedding.length > 0
|
|
310
|
+
? memoryPackage.embedding
|
|
311
|
+
: (memoryPackage.metadata?.embedding || []);
|
|
312
|
+
if (embeddingToEncrypt.length > 0) {
|
|
313
|
+
const embeddingBytes = new TextEncoder().encode(JSON.stringify(embeddingToEncrypt));
|
|
314
|
+
const encryptEmbeddingResult = await this.services.encryption.encrypt(embeddingBytes, keyId, 2);
|
|
315
|
+
encryptedEmbedding = encryptEmbeddingResult.encryptedObject;
|
|
316
|
+
console.log(`✅ Embedding encrypted: ${embeddingToEncrypt.length}D → ${encryptedEmbedding?.length || 0} bytes`);
|
|
317
|
+
}
|
|
318
|
+
console.log(` Using capability: ${memoryCapId}`);
|
|
319
|
+
console.log(` Key ID: ${keyId.substring(0, 20)}...`);
|
|
320
|
+
}
|
|
321
|
+
catch (encryptError) {
|
|
322
|
+
console.error('❌ Encryption failed:', encryptError);
|
|
323
|
+
console.warn('⚠️ Falling back to plaintext storage');
|
|
324
|
+
// Fall back to plaintext if encryption fails
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
console.log('📝 Encryption disabled or services not available - storing plaintext');
|
|
329
|
+
}
|
|
330
|
+
// Include capability metadata for decryption
|
|
331
|
+
const metadata = {
|
|
332
|
+
...memoryPackage.metadata,
|
|
333
|
+
// Add capability info for decryption (CRITICAL for Option A!)
|
|
334
|
+
...(memoryCapId && keyId ? {
|
|
335
|
+
memoryCapId,
|
|
336
|
+
keyId,
|
|
337
|
+
encryptionVersion: 'v2-capability' // Mark as new capability-based encryption
|
|
338
|
+
} : {})
|
|
339
|
+
};
|
|
340
|
+
// Get embedding from root level (correct API) or metadata (legacy fallback)
|
|
341
|
+
const rootEmbedding = memoryPackage.embedding && memoryPackage.embedding.length > 0;
|
|
342
|
+
const metadataEmbedding = memoryPackage.metadata?.embedding && memoryPackage.metadata.embedding.length > 0;
|
|
343
|
+
const embedding = rootEmbedding
|
|
344
|
+
? memoryPackage.embedding
|
|
345
|
+
: (memoryPackage.metadata?.embedding || []);
|
|
346
|
+
if (metadataEmbedding && !rootEmbedding) {
|
|
347
|
+
console.warn('⚠️ Embedding in metadata (legacy) - should be at root level');
|
|
348
|
+
}
|
|
349
|
+
console.log(`📊 Embedding: ${embedding.length}D vector`);
|
|
271
350
|
// Use uploadMemoryPackage method
|
|
272
351
|
const result = await this.services.storage.uploadMemoryPackage({
|
|
273
352
|
content: memoryPackage.content,
|
|
274
|
-
embedding
|
|
275
|
-
metadata
|
|
276
|
-
identity: this.services.config.userAddress
|
|
353
|
+
embedding,
|
|
354
|
+
metadata,
|
|
355
|
+
identity: this.services.config.userAddress,
|
|
356
|
+
encryptedContent, // Pass encrypted content if available
|
|
357
|
+
encryptedEmbedding, // Pass encrypted embedding for Option A v2
|
|
358
|
+
encryptionType
|
|
277
359
|
}, {
|
|
278
360
|
signer: this.services.config.signer,
|
|
279
361
|
epochs: 3,
|
|
@@ -282,32 +364,277 @@ export class StorageNamespace {
|
|
|
282
364
|
return {
|
|
283
365
|
blobId: result.blobId,
|
|
284
366
|
size: 0, // Size not returned by uploadMemoryPackage
|
|
285
|
-
contentType: 'application/json'
|
|
367
|
+
contentType: 'application/json',
|
|
368
|
+
memoryCapId, // Return capability ID for reference
|
|
369
|
+
keyId // Return key ID for reference
|
|
286
370
|
};
|
|
287
371
|
}
|
|
288
372
|
/**
|
|
289
|
-
* Retrieve memory package from Walrus
|
|
373
|
+
* Retrieve memory package from Walrus with optional decryption
|
|
290
374
|
*
|
|
291
375
|
* @param blobId - Blob ID of the memory package
|
|
376
|
+
* @param decryptionContext - Optional context for decrypting SEAL-encrypted content
|
|
292
377
|
* @returns Retrieved memory package with decrypted content
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* // Without decryption (returns encrypted data info)
|
|
382
|
+
* const result = await pdw.storage.retrieveMemoryPackage(blobId);
|
|
383
|
+
*
|
|
384
|
+
* // With decryption
|
|
385
|
+
* const result = await pdw.storage.retrieveMemoryPackage(blobId, {
|
|
386
|
+
* sessionKey,
|
|
387
|
+
* memoryCapId,
|
|
388
|
+
* keyId
|
|
389
|
+
* });
|
|
390
|
+
* ```
|
|
293
391
|
*/
|
|
294
|
-
async retrieveMemoryPackage(blobId) {
|
|
392
|
+
async retrieveMemoryPackage(blobId, decryptionContext) {
|
|
295
393
|
if (!this.services.storage) {
|
|
296
394
|
throw new Error('Storage service not configured.');
|
|
297
395
|
}
|
|
298
396
|
const result = await this.services.storage.retrieveMemoryPackage(blobId);
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
397
|
+
// If not encrypted, return as-is
|
|
398
|
+
if (!result.isEncrypted && result.memoryPackage) {
|
|
399
|
+
return {
|
|
400
|
+
memoryPackage: {
|
|
401
|
+
content: result.memoryPackage.content,
|
|
402
|
+
contentType: result.memoryPackage.contentType || 'text/plain',
|
|
403
|
+
metadata: result.memoryPackage.metadata,
|
|
404
|
+
embedding: result.memoryPackage.embedding,
|
|
405
|
+
createdAt: result.memoryPackage.timestamp
|
|
406
|
+
},
|
|
407
|
+
decryptionStatus: 'not_encrypted'
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
// v2.2 JSON package with encrypted content + encrypted embedding
|
|
411
|
+
if (result.memoryPackage?.version === '2.2' && result.memoryPackage?.encryptedContent) {
|
|
412
|
+
console.log('🔐 Detected v2.2 JSON package (Full Encryption - Content + Embedding)');
|
|
413
|
+
const embeddingDimension = result.memoryPackage.metadata?.embeddingDimension || 0;
|
|
414
|
+
console.log(` embeddingDimension: ${embeddingDimension}D (encrypted on Walrus)`);
|
|
415
|
+
// Return base package (content encrypted, embedding encrypted)
|
|
416
|
+
const basePackage = {
|
|
417
|
+
content: '[ENCRYPTED - requires decryption]',
|
|
418
|
+
contentType: 'text/plain',
|
|
419
|
+
metadata: result.memoryPackage.metadata,
|
|
420
|
+
embedding: [], // Embedding is encrypted, needs decryption
|
|
421
|
+
createdAt: result.memoryPackage.timestamp
|
|
422
|
+
};
|
|
423
|
+
if (decryptionContext && this.services.encryption) {
|
|
424
|
+
try {
|
|
425
|
+
console.log('🔐 Decrypting v2.2 content...');
|
|
426
|
+
// Decrypt content
|
|
427
|
+
const encryptedContentBase64 = result.memoryPackage.encryptedContent;
|
|
428
|
+
const contentBinaryString = atob(encryptedContentBase64);
|
|
429
|
+
const encryptedContentBytes = new Uint8Array(contentBinaryString.length);
|
|
430
|
+
for (let i = 0; i < contentBinaryString.length; i++) {
|
|
431
|
+
encryptedContentBytes[i] = contentBinaryString.charCodeAt(i);
|
|
432
|
+
}
|
|
433
|
+
const decryptedContentData = await this.services.encryption.decrypt({
|
|
434
|
+
encryptedContent: encryptedContentBytes,
|
|
435
|
+
userAddress: this.services.config.userAddress,
|
|
436
|
+
sessionKey: decryptionContext.sessionKey,
|
|
437
|
+
memoryCapId: decryptionContext.memoryCapId,
|
|
438
|
+
keyId: decryptionContext.keyId
|
|
439
|
+
});
|
|
440
|
+
const decryptedContent = new TextDecoder().decode(decryptedContentData);
|
|
441
|
+
console.log(`✅ v2.2 content decrypted: "${decryptedContent.substring(0, 50)}..."`);
|
|
442
|
+
// Decrypt embedding if available
|
|
443
|
+
let decryptedEmbedding = [];
|
|
444
|
+
if (result.memoryPackage.encryptedEmbedding) {
|
|
445
|
+
console.log('🔐 Decrypting v2.2 embedding...');
|
|
446
|
+
const encryptedEmbeddingBase64 = result.memoryPackage.encryptedEmbedding;
|
|
447
|
+
const embeddingBinaryString = atob(encryptedEmbeddingBase64);
|
|
448
|
+
const encryptedEmbeddingBytes = new Uint8Array(embeddingBinaryString.length);
|
|
449
|
+
for (let i = 0; i < embeddingBinaryString.length; i++) {
|
|
450
|
+
encryptedEmbeddingBytes[i] = embeddingBinaryString.charCodeAt(i);
|
|
451
|
+
}
|
|
452
|
+
const decryptedEmbeddingData = await this.services.encryption.decrypt({
|
|
453
|
+
encryptedContent: encryptedEmbeddingBytes,
|
|
454
|
+
userAddress: this.services.config.userAddress,
|
|
455
|
+
sessionKey: decryptionContext.sessionKey,
|
|
456
|
+
memoryCapId: decryptionContext.memoryCapId,
|
|
457
|
+
keyId: decryptionContext.keyId
|
|
458
|
+
});
|
|
459
|
+
const embeddingJson = new TextDecoder().decode(decryptedEmbeddingData);
|
|
460
|
+
decryptedEmbedding = JSON.parse(embeddingJson);
|
|
461
|
+
console.log(`✅ v2.2 embedding decrypted: ${decryptedEmbedding.length}D vector`);
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
memoryPackage: {
|
|
465
|
+
...basePackage,
|
|
466
|
+
content: decryptedContent,
|
|
467
|
+
embedding: decryptedEmbedding
|
|
468
|
+
},
|
|
469
|
+
decryptionStatus: 'success'
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
catch (decryptError) {
|
|
473
|
+
console.error('❌ v2.2 decryption failed:', decryptError.message);
|
|
474
|
+
return {
|
|
475
|
+
memoryPackage: basePackage,
|
|
476
|
+
decryptionStatus: 'failed',
|
|
477
|
+
error: decryptError.message
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
// No decryption context
|
|
482
|
+
return {
|
|
483
|
+
memoryPackage: basePackage,
|
|
484
|
+
decryptionStatus: 'failed',
|
|
485
|
+
error: 'No decryption context provided for v2.2 encrypted package'
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
// v2.1 JSON package with encrypted content only (no embedding on Walrus)
|
|
489
|
+
if (result.memoryPackage?.version === '2.1' && result.memoryPackage?.encryptedContent) {
|
|
490
|
+
console.log('🔐 Detected v2.1 JSON package (Full Encryption - Content only)');
|
|
491
|
+
const embeddingDimension = result.memoryPackage.metadata?.embeddingDimension || 0;
|
|
492
|
+
console.log(` embeddingDimension: ${embeddingDimension}D (stored locally, not on Walrus)`);
|
|
493
|
+
const basePackage = {
|
|
494
|
+
content: '[ENCRYPTED - requires decryption]',
|
|
495
|
+
contentType: 'text/plain',
|
|
304
496
|
metadata: result.memoryPackage.metadata,
|
|
305
|
-
embedding:
|
|
497
|
+
embedding: [], // v2.1 has no embedding on Walrus
|
|
306
498
|
createdAt: result.memoryPackage.timestamp
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
499
|
+
};
|
|
500
|
+
if (decryptionContext && this.services.encryption) {
|
|
501
|
+
try {
|
|
502
|
+
console.log('🔐 Decrypting v2.1 content...');
|
|
503
|
+
const encryptedBase64 = result.memoryPackage.encryptedContent;
|
|
504
|
+
const binaryString = atob(encryptedBase64);
|
|
505
|
+
const encryptedBytes = new Uint8Array(binaryString.length);
|
|
506
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
507
|
+
encryptedBytes[i] = binaryString.charCodeAt(i);
|
|
508
|
+
}
|
|
509
|
+
const decryptedData = await this.services.encryption.decrypt({
|
|
510
|
+
encryptedContent: encryptedBytes,
|
|
511
|
+
userAddress: this.services.config.userAddress,
|
|
512
|
+
sessionKey: decryptionContext.sessionKey,
|
|
513
|
+
memoryCapId: decryptionContext.memoryCapId,
|
|
514
|
+
keyId: decryptionContext.keyId
|
|
515
|
+
});
|
|
516
|
+
const decryptedContent = new TextDecoder().decode(decryptedData);
|
|
517
|
+
console.log(`✅ v2.1 decryption successful: "${decryptedContent.substring(0, 50)}..."`);
|
|
518
|
+
return {
|
|
519
|
+
memoryPackage: {
|
|
520
|
+
...basePackage,
|
|
521
|
+
content: decryptedContent
|
|
522
|
+
},
|
|
523
|
+
decryptionStatus: 'success'
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
catch (decryptError) {
|
|
527
|
+
console.error('❌ v2.1 decryption failed:', decryptError.message);
|
|
528
|
+
return {
|
|
529
|
+
memoryPackage: basePackage,
|
|
530
|
+
decryptionStatus: 'failed',
|
|
531
|
+
error: decryptError.message
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return {
|
|
536
|
+
memoryPackage: basePackage,
|
|
537
|
+
decryptionStatus: 'failed',
|
|
538
|
+
error: 'No decryption context provided for v2.1 encrypted package'
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
// v2.0 JSON package with encrypted content + plaintext embedding (legacy)
|
|
542
|
+
if (result.memoryPackage?.version === '2.0' && result.memoryPackage?.encryptedContent) {
|
|
543
|
+
console.log('📦 Detected v2.0 JSON package with encrypted content (legacy)');
|
|
544
|
+
// Get embedding from root level OR metadata.embedding (fallback for encryption service bug)
|
|
545
|
+
const embeddingArray = result.memoryPackage.embedding?.length > 0
|
|
546
|
+
? result.memoryPackage.embedding
|
|
547
|
+
: result.memoryPackage.metadata?.embedding;
|
|
548
|
+
const embeddingSource = result.memoryPackage.embedding?.length > 0 ? 'root' : 'metadata';
|
|
549
|
+
console.log(` embedding: ${embeddingArray?.length || 0}D (from ${embeddingSource})`);
|
|
550
|
+
// Return embedding even without decryption (for index rebuilding)
|
|
551
|
+
const basePackage = {
|
|
552
|
+
content: '[ENCRYPTED - requires decryption]',
|
|
553
|
+
contentType: 'text/plain',
|
|
554
|
+
metadata: result.memoryPackage.metadata,
|
|
555
|
+
embedding: embeddingArray, // Plaintext embedding available!
|
|
556
|
+
createdAt: result.memoryPackage.timestamp
|
|
557
|
+
};
|
|
558
|
+
if (decryptionContext && this.services.encryption) {
|
|
559
|
+
try {
|
|
560
|
+
console.log('🔐 Decrypting v2.0 encryptedContent...');
|
|
561
|
+
// Convert base64 back to Uint8Array
|
|
562
|
+
const encryptedBase64 = result.memoryPackage.encryptedContent;
|
|
563
|
+
const binaryString = atob(encryptedBase64);
|
|
564
|
+
const encryptedBytes = new Uint8Array(binaryString.length);
|
|
565
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
566
|
+
encryptedBytes[i] = binaryString.charCodeAt(i);
|
|
567
|
+
}
|
|
568
|
+
const decryptedData = await this.services.encryption.decrypt({
|
|
569
|
+
encryptedContent: encryptedBytes,
|
|
570
|
+
userAddress: this.services.config.userAddress,
|
|
571
|
+
sessionKey: decryptionContext.sessionKey,
|
|
572
|
+
memoryCapId: decryptionContext.memoryCapId,
|
|
573
|
+
keyId: decryptionContext.keyId
|
|
574
|
+
});
|
|
575
|
+
const decryptedContent = new TextDecoder().decode(decryptedData);
|
|
576
|
+
console.log(`✅ v2.0 decryption successful, content: "${decryptedContent.substring(0, 50)}..."`);
|
|
577
|
+
return {
|
|
578
|
+
memoryPackage: {
|
|
579
|
+
...basePackage,
|
|
580
|
+
content: decryptedContent
|
|
581
|
+
},
|
|
582
|
+
decryptionStatus: 'success'
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
catch (decryptError) {
|
|
586
|
+
console.error('❌ v2.0 decryption failed:', decryptError.message);
|
|
587
|
+
return {
|
|
588
|
+
memoryPackage: basePackage, // Return with embedding but encrypted content
|
|
589
|
+
decryptionStatus: 'failed',
|
|
590
|
+
error: decryptError.message
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
// No decryption context - return with embedding only
|
|
595
|
+
return {
|
|
596
|
+
memoryPackage: basePackage,
|
|
597
|
+
decryptionStatus: 'failed',
|
|
598
|
+
error: 'No decryption context provided (embedding still available)'
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
// Legacy binary format (v0) - try to decrypt if context provided
|
|
602
|
+
if (decryptionContext && this.services.encryption) {
|
|
603
|
+
try {
|
|
604
|
+
console.log('🔐 Decrypting legacy binary format...');
|
|
605
|
+
const decryptedData = await this.services.encryption.decrypt({
|
|
606
|
+
encryptedContent: result.content,
|
|
607
|
+
userAddress: this.services.config.userAddress,
|
|
608
|
+
sessionKey: decryptionContext.sessionKey,
|
|
609
|
+
memoryCapId: decryptionContext.memoryCapId,
|
|
610
|
+
keyId: decryptionContext.keyId
|
|
611
|
+
});
|
|
612
|
+
const decryptedContent = new TextDecoder().decode(decryptedData);
|
|
613
|
+
console.log(`✅ Legacy decryption successful, content length: ${decryptedContent.length}`);
|
|
614
|
+
return {
|
|
615
|
+
memoryPackage: {
|
|
616
|
+
content: decryptedContent,
|
|
617
|
+
contentType: 'text/plain',
|
|
618
|
+
metadata: result.metadata,
|
|
619
|
+
createdAt: result.metadata.createdTimestamp
|
|
620
|
+
},
|
|
621
|
+
decryptionStatus: 'success'
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
catch (decryptError) {
|
|
625
|
+
console.error('❌ Legacy decryption failed:', decryptError.message);
|
|
626
|
+
return {
|
|
627
|
+
memoryPackage: null,
|
|
628
|
+
decryptionStatus: 'failed',
|
|
629
|
+
error: decryptError.message
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
// Encrypted but no decryption context provided
|
|
634
|
+
return {
|
|
635
|
+
memoryPackage: null,
|
|
636
|
+
decryptionStatus: 'failed',
|
|
637
|
+
error: 'Content is encrypted but no decryption context provided'
|
|
311
638
|
};
|
|
312
639
|
}
|
|
313
640
|
/**
|
|
@@ -348,6 +675,212 @@ export class StorageNamespace {
|
|
|
348
675
|
}
|
|
349
676
|
}
|
|
350
677
|
// ==========================================================================
|
|
678
|
+
// High-Level Decrypt API
|
|
679
|
+
// ==========================================================================
|
|
680
|
+
/**
|
|
681
|
+
* Retrieve and decrypt a memory package with minimal boilerplate.
|
|
682
|
+
* SDK handles all version detection, format conversion, and decryption internally.
|
|
683
|
+
*
|
|
684
|
+
* @param blobId - Blob ID on Walrus
|
|
685
|
+
* @param options - Decryption options
|
|
686
|
+
* @returns Decrypted content, embedding, and metadata
|
|
687
|
+
*
|
|
688
|
+
* @example
|
|
689
|
+
* ```typescript
|
|
690
|
+
* // With sign function (SDK creates session key)
|
|
691
|
+
* const result = await pdw.storage.retrieveAndDecrypt(blobId, {
|
|
692
|
+
* signFn: async (message) => {
|
|
693
|
+
* const sig = await signPersonalMessage({ message: new TextEncoder().encode(message) });
|
|
694
|
+
* return { signature: sig.signature };
|
|
695
|
+
* }
|
|
696
|
+
* });
|
|
697
|
+
*
|
|
698
|
+
* // With existing session key
|
|
699
|
+
* const result = await pdw.storage.retrieveAndDecrypt(blobId, { sessionKey });
|
|
700
|
+
*
|
|
701
|
+
* console.log(result.content); // "my name is Aaron"
|
|
702
|
+
* console.log(result.embedding); // [0.12, -0.34, ...] (3072D)
|
|
703
|
+
* console.log(result.version); // "2.2"
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
706
|
+
async retrieveAndDecrypt(blobId, options = {}) {
|
|
707
|
+
if (!this.services.storage) {
|
|
708
|
+
throw new Error('Storage service not configured.');
|
|
709
|
+
}
|
|
710
|
+
console.log(`🔐 retrieveAndDecrypt: Downloading blob ${blobId}...`);
|
|
711
|
+
// Step 1: Download blob from Walrus
|
|
712
|
+
const blobData = await this.download(blobId);
|
|
713
|
+
console.log(` Downloaded ${blobData.length} bytes`);
|
|
714
|
+
// Step 2: Detect format and parse
|
|
715
|
+
let version = 'legacy';
|
|
716
|
+
let isEncrypted = false;
|
|
717
|
+
let encryptedContentBase64 = null;
|
|
718
|
+
let encryptedEmbeddingBase64 = null;
|
|
719
|
+
let metadata = {};
|
|
720
|
+
let plainEmbedding = [];
|
|
721
|
+
try {
|
|
722
|
+
const blobText = new TextDecoder().decode(blobData);
|
|
723
|
+
const parsed = JSON.parse(blobText);
|
|
724
|
+
// v2.2: Full encryption (content + embedding both encrypted)
|
|
725
|
+
if (parsed.version === '2.2' && parsed.encryptedContent) {
|
|
726
|
+
version = '2.2';
|
|
727
|
+
isEncrypted = true;
|
|
728
|
+
encryptedContentBase64 = parsed.encryptedContent;
|
|
729
|
+
encryptedEmbeddingBase64 = parsed.encryptedEmbedding || null;
|
|
730
|
+
metadata = parsed.metadata || {};
|
|
731
|
+
console.log(` Detected v2.2: encrypted content + encrypted embedding`);
|
|
732
|
+
}
|
|
733
|
+
// v2.1: Encrypted content only (no embedding on Walrus)
|
|
734
|
+
else if (parsed.version === '2.1' && parsed.encryptedContent) {
|
|
735
|
+
version = '2.1';
|
|
736
|
+
isEncrypted = true;
|
|
737
|
+
encryptedContentBase64 = parsed.encryptedContent;
|
|
738
|
+
metadata = parsed.metadata || {};
|
|
739
|
+
console.log(` Detected v2.1: encrypted content only`);
|
|
740
|
+
}
|
|
741
|
+
// v2.0: Encrypted content + plaintext embedding
|
|
742
|
+
else if (parsed.version === '2.0' && parsed.encryptedContent) {
|
|
743
|
+
version = '2.0';
|
|
744
|
+
isEncrypted = true;
|
|
745
|
+
encryptedContentBase64 = parsed.encryptedContent;
|
|
746
|
+
plainEmbedding = parsed.embedding || [];
|
|
747
|
+
metadata = parsed.metadata || {};
|
|
748
|
+
console.log(` Detected v2.0: encrypted content + ${plainEmbedding.length}D plaintext embedding`);
|
|
749
|
+
}
|
|
750
|
+
// v1.0: Plaintext JSON package
|
|
751
|
+
else if (parsed.version && parsed.content) {
|
|
752
|
+
version = 'plaintext';
|
|
753
|
+
isEncrypted = false;
|
|
754
|
+
metadata = parsed.metadata || {};
|
|
755
|
+
plainEmbedding = parsed.embedding || [];
|
|
756
|
+
console.log(` Detected plaintext JSON package`);
|
|
757
|
+
return {
|
|
758
|
+
content: parsed.content,
|
|
759
|
+
embedding: plainEmbedding,
|
|
760
|
+
version,
|
|
761
|
+
isEncrypted,
|
|
762
|
+
metadata,
|
|
763
|
+
blobId
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
catch {
|
|
768
|
+
// Not JSON - check if binary SEAL data
|
|
769
|
+
const isBinary = blobData.some(byte => byte < 32 && byte !== 9 && byte !== 10 && byte !== 13);
|
|
770
|
+
if (isBinary || blobData.some(byte => byte > 127)) {
|
|
771
|
+
version = 'legacy';
|
|
772
|
+
isEncrypted = true;
|
|
773
|
+
console.log(` Detected legacy binary format`);
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
// Plain text content
|
|
777
|
+
version = 'plaintext';
|
|
778
|
+
isEncrypted = false;
|
|
779
|
+
console.log(` Detected plaintext content`);
|
|
780
|
+
return {
|
|
781
|
+
content: new TextDecoder().decode(blobData),
|
|
782
|
+
embedding: [],
|
|
783
|
+
version,
|
|
784
|
+
isEncrypted,
|
|
785
|
+
metadata: {},
|
|
786
|
+
blobId
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
// Step 3: If not encrypted, return as-is
|
|
791
|
+
if (!isEncrypted) {
|
|
792
|
+
return {
|
|
793
|
+
content: new TextDecoder().decode(blobData),
|
|
794
|
+
embedding: plainEmbedding,
|
|
795
|
+
version,
|
|
796
|
+
isEncrypted,
|
|
797
|
+
metadata,
|
|
798
|
+
blobId
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
// Step 4: Get decryption parameters (from options or metadata)
|
|
802
|
+
const memoryCapId = options.memoryCapId || metadata.memoryCapId;
|
|
803
|
+
const keyIdHex = options.keyId || metadata.keyId;
|
|
804
|
+
if (!memoryCapId || !keyIdHex) {
|
|
805
|
+
throw new Error(`Missing decryption parameters. memoryCapId=${!!memoryCapId}, keyId=${!!keyIdHex}. ` +
|
|
806
|
+
`Provide via options or ensure metadata contains these values.`);
|
|
807
|
+
}
|
|
808
|
+
// Step 5: Convert keyId hex string to Uint8Array (SDK handles this!)
|
|
809
|
+
const keyIdBytes = new Uint8Array((keyIdHex.startsWith('0x') ? keyIdHex.slice(2) : keyIdHex)
|
|
810
|
+
.match(/.{1,2}/g)
|
|
811
|
+
.map((byte) => parseInt(byte, 16)));
|
|
812
|
+
// Step 6: Get or create session key
|
|
813
|
+
let sessionKey = options.sessionKey;
|
|
814
|
+
if (!sessionKey) {
|
|
815
|
+
if (!options.signFn) {
|
|
816
|
+
throw new Error('Decryption requires either sessionKey or signFn. ' +
|
|
817
|
+
'Provide signFn to create session key automatically.');
|
|
818
|
+
}
|
|
819
|
+
if (!this.services.encryption) {
|
|
820
|
+
throw new Error('Encryption service not configured.');
|
|
821
|
+
}
|
|
822
|
+
console.log(` Creating session key (will prompt for signature)...`);
|
|
823
|
+
sessionKey = await this.services.encryption.createSessionKey(this.services.config.userAddress, {
|
|
824
|
+
signPersonalMessageFn: async (message) => {
|
|
825
|
+
return options.signFn(message);
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
console.log(` Session key created`);
|
|
829
|
+
}
|
|
830
|
+
// Step 7: Decrypt content
|
|
831
|
+
console.log(` Decrypting content...`);
|
|
832
|
+
// Convert base64 to Uint8Array if needed
|
|
833
|
+
let dataToDecrypt;
|
|
834
|
+
if (encryptedContentBase64) {
|
|
835
|
+
const binaryString = atob(encryptedContentBase64);
|
|
836
|
+
dataToDecrypt = new Uint8Array(binaryString.length);
|
|
837
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
838
|
+
dataToDecrypt[i] = binaryString.charCodeAt(i);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
dataToDecrypt = blobData;
|
|
843
|
+
}
|
|
844
|
+
const decryptedContentData = await this.services.encryption.decrypt({
|
|
845
|
+
encryptedContent: dataToDecrypt,
|
|
846
|
+
userAddress: this.services.config.userAddress,
|
|
847
|
+
sessionKey,
|
|
848
|
+
memoryCapId,
|
|
849
|
+
keyId: keyIdBytes
|
|
850
|
+
});
|
|
851
|
+
const content = new TextDecoder().decode(decryptedContentData);
|
|
852
|
+
console.log(` Content decrypted: "${content.substring(0, 50)}${content.length > 50 ? '...' : ''}"`);
|
|
853
|
+
// Step 8: Decrypt embedding if v2.2
|
|
854
|
+
let embedding = plainEmbedding;
|
|
855
|
+
if (version === '2.2' && encryptedEmbeddingBase64) {
|
|
856
|
+
console.log(` Decrypting embedding...`);
|
|
857
|
+
const embeddingBinaryString = atob(encryptedEmbeddingBase64);
|
|
858
|
+
const encryptedEmbeddingBytes = new Uint8Array(embeddingBinaryString.length);
|
|
859
|
+
for (let i = 0; i < embeddingBinaryString.length; i++) {
|
|
860
|
+
encryptedEmbeddingBytes[i] = embeddingBinaryString.charCodeAt(i);
|
|
861
|
+
}
|
|
862
|
+
const decryptedEmbeddingData = await this.services.encryption.decrypt({
|
|
863
|
+
encryptedContent: encryptedEmbeddingBytes,
|
|
864
|
+
userAddress: this.services.config.userAddress,
|
|
865
|
+
sessionKey,
|
|
866
|
+
memoryCapId,
|
|
867
|
+
keyId: keyIdBytes
|
|
868
|
+
});
|
|
869
|
+
const embeddingJson = new TextDecoder().decode(decryptedEmbeddingData);
|
|
870
|
+
embedding = JSON.parse(embeddingJson);
|
|
871
|
+
console.log(` Embedding decrypted: ${embedding.length}D vector`);
|
|
872
|
+
}
|
|
873
|
+
console.log(`✅ retrieveAndDecrypt complete: ${content.length} chars, ${embedding.length}D embedding`);
|
|
874
|
+
return {
|
|
875
|
+
content,
|
|
876
|
+
embedding,
|
|
877
|
+
version,
|
|
878
|
+
isEncrypted,
|
|
879
|
+
metadata,
|
|
880
|
+
blobId
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
// ==========================================================================
|
|
351
884
|
// Batch Operations (Quilt)
|
|
352
885
|
// ==========================================================================
|
|
353
886
|
/**
|