@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.
Files changed (247) hide show
  1. package/ARCHITECTURE.md +547 -547
  2. package/BENCHMARKS.md +238 -238
  3. package/README.md +310 -181
  4. package/dist/ai-sdk/tools.d.ts +2 -2
  5. package/dist/ai-sdk/tools.js +2 -2
  6. package/dist/client/ClientMemoryManager.js +2 -2
  7. package/dist/client/ClientMemoryManager.js.map +1 -1
  8. package/dist/client/PersonalDataWallet.d.ts.map +1 -1
  9. package/dist/client/SimplePDWClient.d.ts +29 -1
  10. package/dist/client/SimplePDWClient.d.ts.map +1 -1
  11. package/dist/client/SimplePDWClient.js +45 -13
  12. package/dist/client/SimplePDWClient.js.map +1 -1
  13. package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
  14. package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
  15. package/dist/client/namespaces/MemoryNamespace.d.ts +31 -0
  16. package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
  17. package/dist/client/namespaces/MemoryNamespace.js +272 -39
  18. package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
  19. package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
  20. package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
  21. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
  22. package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
  23. package/dist/client/namespaces/consolidated/BlockchainNamespace.js +62 -4
  24. package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
  25. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
  26. package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
  27. package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
  28. package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
  29. package/dist/config/ConfigurationHelper.js +61 -61
  30. package/dist/config/defaults.js +2 -2
  31. package/dist/config/defaults.js.map +1 -1
  32. package/dist/graph/GraphService.js +21 -21
  33. package/dist/graph/GraphService.js.map +1 -1
  34. package/dist/index.d.ts +3 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +3 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
  39. package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
  40. package/dist/infrastructure/seal/EncryptionService.js +37 -15
  41. package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
  42. package/dist/infrastructure/seal/SealService.d.ts +13 -5
  43. package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
  44. package/dist/infrastructure/seal/SealService.js +36 -34
  45. package/dist/infrastructure/seal/SealService.js.map +1 -1
  46. package/dist/langchain/createPDWRAG.js +30 -30
  47. package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
  48. package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
  49. package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
  50. package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
  51. package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
  52. package/dist/retrieval/MemoryRetrievalService.js +44 -4
  53. package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
  54. package/dist/services/CapabilityService.d.ts.map +1 -1
  55. package/dist/services/CapabilityService.js +30 -14
  56. package/dist/services/CapabilityService.js.map +1 -1
  57. package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
  58. package/dist/services/CrossContextPermissionService.js +9 -7
  59. package/dist/services/CrossContextPermissionService.js.map +1 -1
  60. package/dist/services/EmbeddingService.d.ts +28 -1
  61. package/dist/services/EmbeddingService.d.ts.map +1 -1
  62. package/dist/services/EmbeddingService.js +54 -0
  63. package/dist/services/EmbeddingService.js.map +1 -1
  64. package/dist/services/EncryptionService.d.ts.map +1 -1
  65. package/dist/services/EncryptionService.js +6 -5
  66. package/dist/services/EncryptionService.js.map +1 -1
  67. package/dist/services/GeminiAIService.js +309 -309
  68. package/dist/services/IndexManager.d.ts +5 -1
  69. package/dist/services/IndexManager.d.ts.map +1 -1
  70. package/dist/services/IndexManager.js +17 -40
  71. package/dist/services/IndexManager.js.map +1 -1
  72. package/dist/services/QueryService.js +1 -1
  73. package/dist/services/QueryService.js.map +1 -1
  74. package/dist/services/StorageService.d.ts +11 -0
  75. package/dist/services/StorageService.d.ts.map +1 -1
  76. package/dist/services/StorageService.js +73 -10
  77. package/dist/services/StorageService.js.map +1 -1
  78. package/dist/services/TransactionService.d.ts +20 -0
  79. package/dist/services/TransactionService.d.ts.map +1 -1
  80. package/dist/services/TransactionService.js +43 -0
  81. package/dist/services/TransactionService.js.map +1 -1
  82. package/dist/services/ViewService.js +2 -2
  83. package/dist/services/ViewService.js.map +1 -1
  84. package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
  85. package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
  86. package/dist/services/storage/QuiltBatchManager.js +410 -20
  87. package/dist/services/storage/QuiltBatchManager.js.map +1 -1
  88. package/dist/services/storage/index.d.ts +1 -1
  89. package/dist/services/storage/index.d.ts.map +1 -1
  90. package/dist/services/storage/index.js.map +1 -1
  91. package/dist/utils/LRUCache.d.ts +106 -0
  92. package/dist/utils/LRUCache.d.ts.map +1 -0
  93. package/dist/utils/LRUCache.js +281 -0
  94. package/dist/utils/LRUCache.js.map +1 -0
  95. package/dist/utils/index.d.ts +1 -0
  96. package/dist/utils/index.d.ts.map +1 -1
  97. package/dist/utils/index.js +2 -0
  98. package/dist/utils/index.js.map +1 -1
  99. package/dist/utils/memoryIndexOnChain.d.ts +212 -0
  100. package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
  101. package/dist/utils/memoryIndexOnChain.js +312 -0
  102. package/dist/utils/memoryIndexOnChain.js.map +1 -0
  103. package/dist/utils/rebuildIndexNode.d.ts +29 -0
  104. package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
  105. package/dist/utils/rebuildIndexNode.js +366 -98
  106. package/dist/utils/rebuildIndexNode.js.map +1 -1
  107. package/dist/vector/HnswWasmService.d.ts +20 -5
  108. package/dist/vector/HnswWasmService.d.ts.map +1 -1
  109. package/dist/vector/HnswWasmService.js +73 -40
  110. package/dist/vector/HnswWasmService.js.map +1 -1
  111. package/dist/vector/IHnswService.d.ts +10 -1
  112. package/dist/vector/IHnswService.d.ts.map +1 -1
  113. package/dist/vector/IHnswService.js.map +1 -1
  114. package/dist/vector/NodeHnswService.d.ts +16 -0
  115. package/dist/vector/NodeHnswService.d.ts.map +1 -1
  116. package/dist/vector/NodeHnswService.js +84 -5
  117. package/dist/vector/NodeHnswService.js.map +1 -1
  118. package/dist/vector/createHnswService.d.ts +1 -1
  119. package/dist/vector/createHnswService.js +1 -1
  120. package/dist/vector/index.d.ts +1 -1
  121. package/dist/vector/index.js +1 -1
  122. package/package.json +157 -157
  123. package/src/access/PermissionService.ts +635 -635
  124. package/src/aggregation/AggregationService.ts +389 -389
  125. package/src/ai-sdk/PDWVectorStore.ts +715 -715
  126. package/src/ai-sdk/index.ts +65 -65
  127. package/src/ai-sdk/tools.ts +460 -460
  128. package/src/ai-sdk/types.ts +404 -404
  129. package/src/batch/BatchManager.ts +597 -597
  130. package/src/batch/BatchingService.ts +429 -429
  131. package/src/batch/MemoryProcessingCache.ts +492 -492
  132. package/src/batch/index.ts +30 -30
  133. package/src/browser.ts +200 -200
  134. package/src/client/ClientMemoryManager.ts +987 -987
  135. package/src/client/PersonalDataWallet.ts +345 -345
  136. package/src/client/SimplePDWClient.ts +1289 -1222
  137. package/src/client/factory.ts +154 -154
  138. package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
  139. package/src/client/namespaces/BatchNamespace.ts +356 -356
  140. package/src/client/namespaces/CacheNamespace.ts +123 -123
  141. package/src/client/namespaces/CapabilityNamespace.ts +217 -217
  142. package/src/client/namespaces/ClassifyNamespace.ts +169 -169
  143. package/src/client/namespaces/ContextNamespace.ts +297 -297
  144. package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
  145. package/src/client/namespaces/EncryptionNamespace.ts +221 -221
  146. package/src/client/namespaces/GraphNamespace.ts +468 -468
  147. package/src/client/namespaces/IndexNamespace.ts +361 -361
  148. package/src/client/namespaces/MemoryNamespace.ts +1422 -1135
  149. package/src/client/namespaces/PermissionsNamespace.ts +254 -254
  150. package/src/client/namespaces/PipelineNamespace.ts +220 -220
  151. package/src/client/namespaces/SearchNamespace.ts +1049 -1049
  152. package/src/client/namespaces/StorageNamespace.ts +458 -458
  153. package/src/client/namespaces/TxNamespace.ts +260 -260
  154. package/src/client/namespaces/WalletNamespace.ts +243 -243
  155. package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
  156. package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -546
  157. package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
  158. package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
  159. package/src/client/namespaces/consolidated/index.ts +39 -39
  160. package/src/client/signers/KeypairSigner.ts +108 -108
  161. package/src/client/signers/UnifiedSigner.ts +110 -110
  162. package/src/client/signers/WalletAdapterSigner.ts +159 -159
  163. package/src/client/signers/index.ts +26 -26
  164. package/src/config/ConfigurationHelper.ts +412 -412
  165. package/src/config/defaults.ts +51 -51
  166. package/src/config/index.ts +8 -8
  167. package/src/config/validation.ts +70 -70
  168. package/src/core/index.ts +14 -14
  169. package/src/core/interfaces/IService.ts +307 -307
  170. package/src/core/interfaces/index.ts +8 -8
  171. package/src/core/types/capability.ts +297 -297
  172. package/src/core/types/index.ts +870 -870
  173. package/src/core/types/wallet.ts +270 -270
  174. package/src/core/types.ts +9 -9
  175. package/src/core/wallet.ts +222 -222
  176. package/src/embedding/index.ts +19 -19
  177. package/src/embedding/types.ts +357 -357
  178. package/src/errors/index.ts +602 -602
  179. package/src/errors/recovery.ts +461 -461
  180. package/src/errors/validation.ts +567 -567
  181. package/src/generated/pdw/capability.ts +319 -319
  182. package/src/graph/GraphService.ts +887 -887
  183. package/src/graph/KnowledgeGraphManager.ts +728 -728
  184. package/src/graph/index.ts +25 -25
  185. package/src/index.ts +498 -474
  186. package/src/infrastructure/index.ts +22 -22
  187. package/src/infrastructure/seal/EncryptionService.ts +628 -603
  188. package/src/infrastructure/seal/SealService.ts +613 -615
  189. package/src/infrastructure/seal/index.ts +9 -9
  190. package/src/infrastructure/sui/BlockchainManager.ts +627 -627
  191. package/src/infrastructure/sui/SuiService.ts +888 -888
  192. package/src/infrastructure/sui/index.ts +9 -9
  193. package/src/infrastructure/walrus/StorageManager.ts +604 -604
  194. package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
  195. package/src/infrastructure/walrus/index.ts +9 -9
  196. package/src/langchain/PDWEmbeddings.ts +145 -145
  197. package/src/langchain/PDWVectorStore.ts +456 -456
  198. package/src/langchain/createPDWRAG.ts +303 -303
  199. package/src/langchain/index.ts +47 -47
  200. package/src/permissions/ConsentRepository.browser.ts +249 -249
  201. package/src/permissions/ConsentRepository.ts +364 -364
  202. package/src/pipeline/MemoryPipeline.ts +862 -862
  203. package/src/pipeline/PipelineManager.ts +683 -683
  204. package/src/pipeline/index.ts +26 -26
  205. package/src/retrieval/AdvancedSearchService.ts +629 -629
  206. package/src/retrieval/MemoryAnalyticsService.ts +711 -711
  207. package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
  208. package/src/retrieval/MemoryRetrievalService.ts +904 -830
  209. package/src/retrieval/index.ts +42 -42
  210. package/src/services/BatchService.ts +352 -352
  211. package/src/services/CapabilityService.ts +464 -448
  212. package/src/services/ClassifierService.ts +465 -465
  213. package/src/services/CrossContextPermissionService.ts +486 -484
  214. package/src/services/EmbeddingService.ts +771 -706
  215. package/src/services/EncryptionService.ts +712 -711
  216. package/src/services/GeminiAIService.ts +753 -753
  217. package/src/services/IndexManager.ts +977 -1004
  218. package/src/services/MemoryIndexService.ts +1003 -1003
  219. package/src/services/MemoryService.ts +369 -369
  220. package/src/services/QueryService.ts +890 -890
  221. package/src/services/StorageService.ts +1182 -1111
  222. package/src/services/TransactionService.ts +838 -790
  223. package/src/services/VectorService.ts +462 -462
  224. package/src/services/ViewService.ts +484 -484
  225. package/src/services/index.ts +25 -25
  226. package/src/services/storage/BlobAttributesManager.ts +333 -333
  227. package/src/services/storage/KnowledgeGraphManager.ts +425 -425
  228. package/src/services/storage/MemorySearchManager.ts +387 -387
  229. package/src/services/storage/QuiltBatchManager.ts +1130 -660
  230. package/src/services/storage/WalrusMetadataManager.ts +268 -268
  231. package/src/services/storage/WalrusStorageManager.ts +287 -287
  232. package/src/services/storage/index.ts +57 -52
  233. package/src/types/index.ts +13 -13
  234. package/src/utils/LRUCache.ts +378 -0
  235. package/src/utils/index.ts +76 -68
  236. package/src/utils/memoryIndexOnChain.ts +507 -0
  237. package/src/utils/rebuildIndex.ts +290 -290
  238. package/src/utils/rebuildIndexNode.ts +771 -424
  239. package/src/vector/BrowserHnswIndexService.ts +758 -758
  240. package/src/vector/HnswWasmService.ts +731 -679
  241. package/src/vector/IHnswService.ts +233 -224
  242. package/src/vector/NodeHnswService.ts +833 -735
  243. package/src/vector/VectorManager.ts +478 -478
  244. package/src/vector/createHnswService.ts +135 -135
  245. package/src/vector/index.ts +56 -56
  246. package/src/wallet/ContextWalletService.ts +656 -656
  247. package/src/wallet/MainWalletService.ts +317 -317
@@ -1,628 +1,628 @@
1
- /**
2
- * BlockchainManager - Memory Ownership & Metadata Management
3
- *
4
- * Orchestrates blockchain operations for memory records, manages ownership,
5
- * and provides seamless integration with memory processing pipeline.
6
- */
7
-
8
- import { SuiService, MemoryRecord, MemoryIndex, MemoryMetadata, TransactionResult } from './SuiService';
9
- import { ProcessedMemory } from '../../embedding/types';
10
-
11
- export interface BlockchainManagerConfig {
12
- suiConfig?: {
13
- network?: 'testnet' | 'mainnet' | 'devnet' | 'localnet';
14
- packageId?: string;
15
- adminPrivateKey?: string;
16
- enableBatching?: boolean;
17
- batchSize?: number;
18
- batchDelayMs?: number;
19
- };
20
- enableOwnershipTracking?: boolean;
21
- enableMetadataSync?: boolean;
22
- retryAttempts?: number;
23
- enableCaching?: boolean;
24
- }
25
-
26
- export interface MemoryOwnershipRecord {
27
- memoryId: string;
28
- userId: string;
29
- blockchainRecordId: string;
30
- vectorId: number;
31
- blobId: string;
32
- category: string;
33
- createdAt: Date;
34
- transactionDigest: string;
35
- version: number;
36
- }
37
-
38
- export interface IndexOwnershipRecord {
39
- indexId: string;
40
- userId: string;
41
- blockchainRecordId: string;
42
- indexBlobId: string;
43
- graphBlobId: string;
44
- version: number;
45
- createdAt: Date;
46
- lastUpdated: Date;
47
- }
48
-
49
- export interface BlockchainOperation {
50
- id: string;
51
- type: 'create_memory' | 'create_index' | 'update_index';
52
- userId: string;
53
- status: 'pending' | 'processing' | 'completed' | 'failed';
54
- data: any;
55
- result?: TransactionResult;
56
- createdAt: Date;
57
- completedAt?: Date;
58
- error?: string;
59
- }
60
-
61
- export interface OwnershipVerification {
62
- isOwner: boolean;
63
- ownerAddress: string;
64
- recordExists: boolean;
65
- lastVerified: Date;
66
- blockchainRecord?: MemoryRecord | MemoryIndex;
67
- }
68
-
69
- export interface BlockchainStats {
70
- totalRecords: number;
71
- memoryRecords: number;
72
- indexRecords: number;
73
- successfulOperations: number;
74
- failedOperations: number;
75
- pendingOperations: number;
76
- averageProcessingTime: number;
77
- gasEfficiency: {
78
- averageGasUsed: number;
79
- totalGasCost: number;
80
- optimizationSavings: number;
81
- };
82
- networkHealth: string;
83
- }
84
-
85
- /**
86
- * Blockchain manager for memory ownership and decentralized metadata
87
- */
88
- export class BlockchainManager {
89
- private suiService: SuiService;
90
- private ownershipCache = new Map<string, MemoryOwnershipRecord>();
91
- private indexCache = new Map<string, IndexOwnershipRecord>();
92
- private operations = new Map<string, BlockchainOperation>();
93
- private verificationCache = new Map<string, OwnershipVerification>();
94
-
95
- private readonly config: Required<BlockchainManagerConfig>;
96
- private stats = {
97
- totalRecords: 0,
98
- memoryRecords: 0,
99
- indexRecords: 0,
100
- successfulOperations: 0,
101
- failedOperations: 0,
102
- pendingOperations: 0,
103
- averageProcessingTime: 0,
104
- totalProcessingTime: 0
105
- };
106
-
107
- constructor(config: BlockchainManagerConfig = {}) {
108
- this.config = {
109
- suiConfig: {
110
- network: config.suiConfig?.network || 'testnet',
111
- packageId: config.suiConfig?.packageId,
112
- adminPrivateKey: config.suiConfig?.adminPrivateKey,
113
- enableBatching: config.suiConfig?.enableBatching !== false,
114
- batchSize: config.suiConfig?.batchSize || 10,
115
- batchDelayMs: config.suiConfig?.batchDelayMs || 5000
116
- },
117
- enableOwnershipTracking: config.enableOwnershipTracking !== false,
118
- enableMetadataSync: config.enableMetadataSync !== false,
119
- retryAttempts: config.retryAttempts || 3,
120
- enableCaching: config.enableCaching !== false
121
- };
122
-
123
- // Initialize Sui service
124
- this.suiService = new SuiService(this.config.suiConfig);
125
- }
126
-
127
- // ==================== MEMORY RECORD OPERATIONS ====================
128
-
129
- /**
130
- * Create blockchain record for processed memory
131
- */
132
- async createMemoryRecord(
133
- memory: ProcessedMemory,
134
- userId: string,
135
- options: {
136
- priority?: 'low' | 'normal' | 'high';
137
- enableBatching?: boolean;
138
- customMetadata?: Record<string, string>;
139
- } = {}
140
- ): Promise<MemoryOwnershipRecord> {
141
- const operationId = this.generateOperationId();
142
-
143
- try {
144
- // Create operation record
145
- const operation: BlockchainOperation = {
146
- id: operationId,
147
- type: 'create_memory',
148
- userId,
149
- status: 'pending',
150
- data: { memory, options },
151
- createdAt: new Date()
152
- };
153
-
154
- this.operations.set(operationId, operation);
155
- this.stats.pendingOperations++;
156
-
157
- // Prepare metadata for blockchain
158
- const blockchainMetadata = this.convertToBlockchainMetadata(memory, options.customMetadata);
159
-
160
- // Create blockchain record
161
- operation.status = 'processing';
162
- const startTime = Date.now();
163
-
164
- const result = await this.suiService.createMemoryRecord(
165
- userId,
166
- memory.category || 'general',
167
- memory.vectorId || 0,
168
- memory.blobId || '',
169
- blockchainMetadata,
170
- {
171
- enableBatching: options.enableBatching,
172
- priority: this.mapPriority(options.priority)
173
- }
174
- );
175
-
176
- const processingTime = Date.now() - startTime;
177
-
178
- if (result.success) {
179
- operation.status = 'completed';
180
- operation.result = result;
181
- operation.completedAt = new Date();
182
-
183
- // Create ownership record
184
- const ownershipRecord: MemoryOwnershipRecord = {
185
- memoryId: memory.id,
186
- userId,
187
- blockchainRecordId: result.objectId || '',
188
- vectorId: memory.vectorId || 0,
189
- blobId: memory.blobId || '',
190
- category: memory.category || 'general',
191
- createdAt: new Date(),
192
- transactionDigest: result.digest,
193
- version: 1
194
- };
195
-
196
- // Cache the record
197
- if (this.config.enableCaching) {
198
- this.ownershipCache.set(memory.id, ownershipRecord);
199
- }
200
-
201
- // Update statistics
202
- this.stats.successfulOperations++;
203
- this.stats.memoryRecords++;
204
- this.stats.totalRecords++;
205
- this.updateProcessingTimeStats(processingTime);
206
-
207
- return ownershipRecord;
208
-
209
- } else {
210
- operation.status = 'failed';
211
- operation.error = result.error;
212
- this.stats.failedOperations++;
213
-
214
- throw new Error(`Blockchain record creation failed: ${result.error}`);
215
- }
216
-
217
- } catch (error) {
218
- const operation = this.operations.get(operationId);
219
- if (operation) {
220
- operation.status = 'failed';
221
- operation.error = error instanceof Error ? error.message : String(error);
222
- }
223
-
224
- this.stats.failedOperations++;
225
- this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
226
-
227
- throw new Error(`Failed to create memory record: ${error instanceof Error ? error.message : String(error)}`);
228
- } finally {
229
- this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
230
- }
231
- }
232
-
233
- /**
234
- * Create or update memory index on blockchain
235
- */
236
- async createOrUpdateMemoryIndex(
237
- userId: string,
238
- indexBlobId: string,
239
- graphBlobId: string,
240
- existingIndexId?: string,
241
- options: {
242
- priority?: 'low' | 'normal' | 'high';
243
- enableBatching?: boolean;
244
- expectedVersion?: number;
245
- } = {}
246
- ): Promise<IndexOwnershipRecord> {
247
- const operationId = this.generateOperationId();
248
-
249
- try {
250
- const operation: BlockchainOperation = {
251
- id: operationId,
252
- type: existingIndexId ? 'update_index' : 'create_index',
253
- userId,
254
- status: 'pending',
255
- data: { indexBlobId, graphBlobId, existingIndexId, options },
256
- createdAt: new Date()
257
- };
258
-
259
- this.operations.set(operationId, operation);
260
- this.stats.pendingOperations++;
261
-
262
- operation.status = 'processing';
263
- const startTime = Date.now();
264
-
265
- let result: TransactionResult;
266
-
267
- if (existingIndexId && options.expectedVersion !== undefined) {
268
- // Update existing index
269
- result = await this.suiService.updateMemoryIndex(
270
- existingIndexId,
271
- userId,
272
- options.expectedVersion,
273
- indexBlobId,
274
- graphBlobId,
275
- {
276
- enableBatching: options.enableBatching,
277
- priority: this.mapPriority(options.priority)
278
- }
279
- );
280
- } else {
281
- // Create new index
282
- result = await this.suiService.createMemoryIndex(
283
- userId,
284
- indexBlobId,
285
- graphBlobId,
286
- {
287
- enableBatching: options.enableBatching,
288
- priority: this.mapPriority(options.priority)
289
- }
290
- );
291
- }
292
-
293
- const processingTime = Date.now() - startTime;
294
-
295
- if (result.success) {
296
- operation.status = 'completed';
297
- operation.result = result;
298
- operation.completedAt = new Date();
299
-
300
- // Create or update index record
301
- const indexRecord: IndexOwnershipRecord = {
302
- indexId: `index_${userId}_${Date.now()}`,
303
- userId,
304
- blockchainRecordId: result.objectId || existingIndexId || '',
305
- indexBlobId,
306
- graphBlobId,
307
- version: existingIndexId ? (options.expectedVersion || 1) + 1 : 1,
308
- createdAt: existingIndexId ? (this.indexCache.get(existingIndexId)?.createdAt || new Date()) : new Date(),
309
- lastUpdated: new Date()
310
- };
311
-
312
- // Cache the record
313
- if (this.config.enableCaching) {
314
- this.indexCache.set(indexRecord.indexId, indexRecord);
315
- }
316
-
317
- // Update statistics
318
- this.stats.successfulOperations++;
319
- if (!existingIndexId) {
320
- this.stats.indexRecords++;
321
- this.stats.totalRecords++;
322
- }
323
- this.updateProcessingTimeStats(processingTime);
324
-
325
- return indexRecord;
326
-
327
- } else {
328
- operation.status = 'failed';
329
- operation.error = result.error;
330
- this.stats.failedOperations++;
331
-
332
- throw new Error(`Index operation failed: ${result.error}`);
333
- }
334
-
335
- } catch (error) {
336
- const operation = this.operations.get(operationId);
337
- if (operation) {
338
- operation.status = 'failed';
339
- operation.error = error instanceof Error ? error.message : String(error);
340
- }
341
-
342
- this.stats.failedOperations++;
343
- this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
344
-
345
- throw new Error(`Failed to create/update index: ${error instanceof Error ? error.message : String(error)}`);
346
- } finally {
347
- this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
348
- }
349
- }
350
-
351
- // ==================== OWNERSHIP VERIFICATION ====================
352
-
353
- /**
354
- * Verify memory ownership
355
- */
356
- async verifyOwnership(
357
- memoryId: string,
358
- userId: string,
359
- options: {
360
- useCache?: boolean;
361
- forceRefresh?: boolean;
362
- } = {}
363
- ): Promise<OwnershipVerification> {
364
- const cacheKey = `${memoryId}_${userId}`;
365
-
366
- // Check cache first
367
- if (options.useCache && !options.forceRefresh) {
368
- const cached = this.verificationCache.get(cacheKey);
369
- if (cached && this.isCacheValid(cached.lastVerified)) {
370
- return cached;
371
- }
372
- }
373
-
374
- try {
375
- // Get ownership record
376
- const ownershipRecord = this.ownershipCache.get(memoryId);
377
-
378
- if (!ownershipRecord) {
379
- // Try to get from blockchain
380
- const userRecords = await this.suiService.getUserMemoryRecords(userId);
381
- const blockchainRecord = userRecords.find(r => r.id === memoryId);
382
-
383
- const verification: OwnershipVerification = {
384
- isOwner: blockchainRecord ? blockchainRecord.owner === userId : false,
385
- ownerAddress: blockchainRecord?.owner || '',
386
- recordExists: !!blockchainRecord,
387
- lastVerified: new Date(),
388
- blockchainRecord
389
- };
390
-
391
- // Cache the result
392
- this.verificationCache.set(cacheKey, verification);
393
- return verification;
394
- }
395
-
396
- // Verify ownership record
397
- const verification: OwnershipVerification = {
398
- isOwner: ownershipRecord.userId === userId,
399
- ownerAddress: ownershipRecord.userId,
400
- recordExists: true,
401
- lastVerified: new Date()
402
- };
403
-
404
- // Cache the result
405
- this.verificationCache.set(cacheKey, verification);
406
- return verification;
407
-
408
- } catch (error) {
409
- console.error('Ownership verification failed:', error);
410
-
411
- return {
412
- isOwner: false,
413
- ownerAddress: '',
414
- recordExists: false,
415
- lastVerified: new Date()
416
- };
417
- }
418
- }
419
-
420
- /**
421
- * Get user's memory ownership records
422
- */
423
- async getUserOwnershipRecords(userId: string): Promise<{
424
- memoryRecords: MemoryOwnershipRecord[];
425
- indexRecords: IndexOwnershipRecord[];
426
- }> {
427
- try {
428
- // Get from cache
429
- const memoryRecords = Array.from(this.ownershipCache.values())
430
- .filter(record => record.userId === userId);
431
-
432
- const indexRecords = Array.from(this.indexCache.values())
433
- .filter(record => record.userId === userId);
434
-
435
- // Get from blockchain if cache is empty or incomplete
436
- if (memoryRecords.length === 0) {
437
- const blockchainRecords = await this.suiService.getUserMemoryRecords(userId);
438
-
439
- for (const bcRecord of blockchainRecords) {
440
- const ownershipRecord: MemoryOwnershipRecord = {
441
- memoryId: bcRecord.id,
442
- userId: bcRecord.owner,
443
- blockchainRecordId: bcRecord.id,
444
- vectorId: bcRecord.vectorId,
445
- blobId: bcRecord.blobId,
446
- category: bcRecord.category,
447
- createdAt: bcRecord.createdAt,
448
- transactionDigest: '', // Not available from query
449
- version: bcRecord.version
450
- };
451
-
452
- memoryRecords.push(ownershipRecord);
453
-
454
- if (this.config.enableCaching) {
455
- this.ownershipCache.set(bcRecord.id, ownershipRecord);
456
- }
457
- }
458
- }
459
-
460
- return { memoryRecords, indexRecords };
461
-
462
- } catch (error) {
463
- console.error('Failed to get user ownership records:', error);
464
- return { memoryRecords: [], indexRecords: [] };
465
- }
466
- }
467
-
468
- // ==================== BATCH OPERATIONS ====================
469
-
470
- /**
471
- * Process multiple memory records in batch
472
- */
473
- async createMemoryRecordsBatch(
474
- memories: Array<{
475
- memory: ProcessedMemory;
476
- userId: string;
477
- customMetadata?: Record<string, string>;
478
- }>,
479
- options: {
480
- batchSize?: number;
481
- onProgress?: (completed: number, total: number) => void;
482
- } = {}
483
- ): Promise<Array<MemoryOwnershipRecord | { error: string; memoryId: string }>> {
484
- const batchSize = options.batchSize || 5;
485
- const results: Array<MemoryOwnershipRecord | { error: string; memoryId: string }> = [];
486
-
487
- // Process in batches
488
- for (let i = 0; i < memories.length; i += batchSize) {
489
- const batch = memories.slice(i, i + batchSize);
490
-
491
- const batchPromises = batch.map(async ({ memory, userId, customMetadata }) => {
492
- try {
493
- return await this.createMemoryRecord(memory, userId, {
494
- enableBatching: true,
495
- customMetadata
496
- });
497
- } catch (error) {
498
- return { error: error instanceof Error ? error.message : String(error), memoryId: memory.id };
499
- }
500
- });
501
-
502
- const batchResults = await Promise.all(batchPromises);
503
- results.push(...batchResults);
504
-
505
- // Progress callback
506
- if (options.onProgress) {
507
- options.onProgress(i + batch.length, memories.length);
508
- }
509
- }
510
-
511
- return results;
512
- }
513
-
514
- /**
515
- * Flush pending blockchain operations
516
- */
517
- async flushPendingOperations(): Promise<TransactionResult[]> {
518
- return await this.suiService.flushBatchQueue();
519
- }
520
-
521
- // ==================== ANALYTICS & MONITORING ====================
522
-
523
- /**
524
- * Get comprehensive blockchain statistics
525
- */
526
- getBlockchainStats(): BlockchainStats {
527
- const suiStats = this.suiService.getStats();
528
-
529
- return {
530
- totalRecords: this.stats.totalRecords,
531
- memoryRecords: this.stats.memoryRecords,
532
- indexRecords: this.stats.indexRecords,
533
- successfulOperations: this.stats.successfulOperations,
534
- failedOperations: this.stats.failedOperations,
535
- pendingOperations: this.stats.pendingOperations,
536
- averageProcessingTime: this.stats.averageProcessingTime,
537
- gasEfficiency: {
538
- averageGasUsed: suiStats.averageGasUsed,
539
- totalGasCost: suiStats.totalGasCost,
540
- optimizationSavings: suiStats.batchedTransactions * 100 // Estimated savings
541
- },
542
- networkHealth: suiStats.networkHealth
543
- };
544
- }
545
-
546
- /**
547
- * Get operation status
548
- */
549
- getOperationStatus(operationId: string): BlockchainOperation | null {
550
- return this.operations.get(operationId) || null;
551
- }
552
-
553
- /**
554
- * Get pending operations
555
- */
556
- getPendingOperations(): BlockchainOperation[] {
557
- return Array.from(this.operations.values())
558
- .filter(op => op.status === 'pending' || op.status === 'processing');
559
- }
560
-
561
- /**
562
- * Clear caches and reset
563
- */
564
- clearCaches(): void {
565
- this.ownershipCache.clear();
566
- this.indexCache.clear();
567
- this.verificationCache.clear();
568
- this.operations.clear();
569
- }
570
-
571
- // ==================== PRIVATE METHODS ====================
572
-
573
- private convertToBlockchainMetadata(
574
- memory: ProcessedMemory,
575
- customMetadata?: Record<string, string>
576
- ): MemoryMetadata {
577
- return {
578
- contentType: 'text/plain',
579
- contentSize: memory.content ? memory.content.length : 0,
580
- contentHash: this.generateContentHash(memory.content),
581
- category: memory.category || 'general',
582
- topic: memory.metadata?.topic || `Memory about ${memory.category || 'general'}`,
583
- importance: memory.metadata?.importance || 5,
584
- embeddingBlobId: memory.blobId || '',
585
- embeddingDimension: memory.embedding ? memory.embedding.length : 3072,
586
- createdTimestamp: memory.createdAt?.getTime() || Date.now(),
587
- updatedTimestamp: memory.processedAt?.getTime() || memory.createdAt?.getTime() || Date.now(),
588
- customMetadata: {
589
- memoryId: memory.id,
590
- embeddingModel: memory.embeddingModel || 'gemini',
591
- ...customMetadata
592
- }
593
- };
594
- }
595
-
596
- private mapPriority(priority?: 'low' | 'normal' | 'high'): number {
597
- const priorityMap = { low: 1, normal: 2, high: 3 };
598
- return priorityMap[priority || 'normal'];
599
- }
600
-
601
- private generateContentHash(content: string): string {
602
- // Simple hash - replace with proper hashing in production
603
- let hash = 0;
604
- for (let i = 0; i < content.length; i++) {
605
- const char = content.charCodeAt(i);
606
- hash = ((hash << 5) - hash) + char;
607
- hash = hash & hash; // Convert to 32bit integer
608
- }
609
- return hash.toString(16);
610
- }
611
-
612
- private generateOperationId(): string {
613
- return `op_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
614
- }
615
-
616
- private updateProcessingTimeStats(processingTime: number): void {
617
- this.stats.totalProcessingTime += processingTime;
618
- this.stats.averageProcessingTime =
619
- this.stats.totalProcessingTime / this.stats.successfulOperations;
620
- }
621
-
622
- private isCacheValid(timestamp: Date): boolean {
623
- const CACHE_TTL_MS = 10 * 60 * 1000; // 10 minutes
624
- return Date.now() - timestamp.getTime() < CACHE_TTL_MS;
625
- }
626
- }
627
-
1
+ /**
2
+ * BlockchainManager - Memory Ownership & Metadata Management
3
+ *
4
+ * Orchestrates blockchain operations for memory records, manages ownership,
5
+ * and provides seamless integration with memory processing pipeline.
6
+ */
7
+
8
+ import { SuiService, MemoryRecord, MemoryIndex, MemoryMetadata, TransactionResult } from './SuiService';
9
+ import { ProcessedMemory } from '../../embedding/types';
10
+
11
+ export interface BlockchainManagerConfig {
12
+ suiConfig?: {
13
+ network?: 'testnet' | 'mainnet' | 'devnet' | 'localnet';
14
+ packageId?: string;
15
+ adminPrivateKey?: string;
16
+ enableBatching?: boolean;
17
+ batchSize?: number;
18
+ batchDelayMs?: number;
19
+ };
20
+ enableOwnershipTracking?: boolean;
21
+ enableMetadataSync?: boolean;
22
+ retryAttempts?: number;
23
+ enableCaching?: boolean;
24
+ }
25
+
26
+ export interface MemoryOwnershipRecord {
27
+ memoryId: string;
28
+ userId: string;
29
+ blockchainRecordId: string;
30
+ vectorId: number;
31
+ blobId: string;
32
+ category: string;
33
+ createdAt: Date;
34
+ transactionDigest: string;
35
+ version: number;
36
+ }
37
+
38
+ export interface IndexOwnershipRecord {
39
+ indexId: string;
40
+ userId: string;
41
+ blockchainRecordId: string;
42
+ indexBlobId: string;
43
+ graphBlobId: string;
44
+ version: number;
45
+ createdAt: Date;
46
+ lastUpdated: Date;
47
+ }
48
+
49
+ export interface BlockchainOperation {
50
+ id: string;
51
+ type: 'create_memory' | 'create_index' | 'update_index';
52
+ userId: string;
53
+ status: 'pending' | 'processing' | 'completed' | 'failed';
54
+ data: any;
55
+ result?: TransactionResult;
56
+ createdAt: Date;
57
+ completedAt?: Date;
58
+ error?: string;
59
+ }
60
+
61
+ export interface OwnershipVerification {
62
+ isOwner: boolean;
63
+ ownerAddress: string;
64
+ recordExists: boolean;
65
+ lastVerified: Date;
66
+ blockchainRecord?: MemoryRecord | MemoryIndex;
67
+ }
68
+
69
+ export interface BlockchainStats {
70
+ totalRecords: number;
71
+ memoryRecords: number;
72
+ indexRecords: number;
73
+ successfulOperations: number;
74
+ failedOperations: number;
75
+ pendingOperations: number;
76
+ averageProcessingTime: number;
77
+ gasEfficiency: {
78
+ averageGasUsed: number;
79
+ totalGasCost: number;
80
+ optimizationSavings: number;
81
+ };
82
+ networkHealth: string;
83
+ }
84
+
85
+ /**
86
+ * Blockchain manager for memory ownership and decentralized metadata
87
+ */
88
+ export class BlockchainManager {
89
+ private suiService: SuiService;
90
+ private ownershipCache = new Map<string, MemoryOwnershipRecord>();
91
+ private indexCache = new Map<string, IndexOwnershipRecord>();
92
+ private operations = new Map<string, BlockchainOperation>();
93
+ private verificationCache = new Map<string, OwnershipVerification>();
94
+
95
+ private readonly config: Required<BlockchainManagerConfig>;
96
+ private stats = {
97
+ totalRecords: 0,
98
+ memoryRecords: 0,
99
+ indexRecords: 0,
100
+ successfulOperations: 0,
101
+ failedOperations: 0,
102
+ pendingOperations: 0,
103
+ averageProcessingTime: 0,
104
+ totalProcessingTime: 0
105
+ };
106
+
107
+ constructor(config: BlockchainManagerConfig = {}) {
108
+ this.config = {
109
+ suiConfig: {
110
+ network: config.suiConfig?.network || 'testnet',
111
+ packageId: config.suiConfig?.packageId,
112
+ adminPrivateKey: config.suiConfig?.adminPrivateKey,
113
+ enableBatching: config.suiConfig?.enableBatching !== false,
114
+ batchSize: config.suiConfig?.batchSize || 10,
115
+ batchDelayMs: config.suiConfig?.batchDelayMs || 5000
116
+ },
117
+ enableOwnershipTracking: config.enableOwnershipTracking !== false,
118
+ enableMetadataSync: config.enableMetadataSync !== false,
119
+ retryAttempts: config.retryAttempts || 3,
120
+ enableCaching: config.enableCaching !== false
121
+ };
122
+
123
+ // Initialize Sui service
124
+ this.suiService = new SuiService(this.config.suiConfig);
125
+ }
126
+
127
+ // ==================== MEMORY RECORD OPERATIONS ====================
128
+
129
+ /**
130
+ * Create blockchain record for processed memory
131
+ */
132
+ async createMemoryRecord(
133
+ memory: ProcessedMemory,
134
+ userId: string,
135
+ options: {
136
+ priority?: 'low' | 'normal' | 'high';
137
+ enableBatching?: boolean;
138
+ customMetadata?: Record<string, string>;
139
+ } = {}
140
+ ): Promise<MemoryOwnershipRecord> {
141
+ const operationId = this.generateOperationId();
142
+
143
+ try {
144
+ // Create operation record
145
+ const operation: BlockchainOperation = {
146
+ id: operationId,
147
+ type: 'create_memory',
148
+ userId,
149
+ status: 'pending',
150
+ data: { memory, options },
151
+ createdAt: new Date()
152
+ };
153
+
154
+ this.operations.set(operationId, operation);
155
+ this.stats.pendingOperations++;
156
+
157
+ // Prepare metadata for blockchain
158
+ const blockchainMetadata = this.convertToBlockchainMetadata(memory, options.customMetadata);
159
+
160
+ // Create blockchain record
161
+ operation.status = 'processing';
162
+ const startTime = Date.now();
163
+
164
+ const result = await this.suiService.createMemoryRecord(
165
+ userId,
166
+ memory.category || 'general',
167
+ memory.vectorId || 0,
168
+ memory.blobId || '',
169
+ blockchainMetadata,
170
+ {
171
+ enableBatching: options.enableBatching,
172
+ priority: this.mapPriority(options.priority)
173
+ }
174
+ );
175
+
176
+ const processingTime = Date.now() - startTime;
177
+
178
+ if (result.success) {
179
+ operation.status = 'completed';
180
+ operation.result = result;
181
+ operation.completedAt = new Date();
182
+
183
+ // Create ownership record
184
+ const ownershipRecord: MemoryOwnershipRecord = {
185
+ memoryId: memory.id,
186
+ userId,
187
+ blockchainRecordId: result.objectId || '',
188
+ vectorId: memory.vectorId || 0,
189
+ blobId: memory.blobId || '',
190
+ category: memory.category || 'general',
191
+ createdAt: new Date(),
192
+ transactionDigest: result.digest,
193
+ version: 1
194
+ };
195
+
196
+ // Cache the record
197
+ if (this.config.enableCaching) {
198
+ this.ownershipCache.set(memory.id, ownershipRecord);
199
+ }
200
+
201
+ // Update statistics
202
+ this.stats.successfulOperations++;
203
+ this.stats.memoryRecords++;
204
+ this.stats.totalRecords++;
205
+ this.updateProcessingTimeStats(processingTime);
206
+
207
+ return ownershipRecord;
208
+
209
+ } else {
210
+ operation.status = 'failed';
211
+ operation.error = result.error;
212
+ this.stats.failedOperations++;
213
+
214
+ throw new Error(`Blockchain record creation failed: ${result.error}`);
215
+ }
216
+
217
+ } catch (error) {
218
+ const operation = this.operations.get(operationId);
219
+ if (operation) {
220
+ operation.status = 'failed';
221
+ operation.error = error instanceof Error ? error.message : String(error);
222
+ }
223
+
224
+ this.stats.failedOperations++;
225
+ this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
226
+
227
+ throw new Error(`Failed to create memory record: ${error instanceof Error ? error.message : String(error)}`);
228
+ } finally {
229
+ this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Create or update memory index on blockchain
235
+ */
236
+ async createOrUpdateMemoryIndex(
237
+ userId: string,
238
+ indexBlobId: string,
239
+ graphBlobId: string,
240
+ existingIndexId?: string,
241
+ options: {
242
+ priority?: 'low' | 'normal' | 'high';
243
+ enableBatching?: boolean;
244
+ expectedVersion?: number;
245
+ } = {}
246
+ ): Promise<IndexOwnershipRecord> {
247
+ const operationId = this.generateOperationId();
248
+
249
+ try {
250
+ const operation: BlockchainOperation = {
251
+ id: operationId,
252
+ type: existingIndexId ? 'update_index' : 'create_index',
253
+ userId,
254
+ status: 'pending',
255
+ data: { indexBlobId, graphBlobId, existingIndexId, options },
256
+ createdAt: new Date()
257
+ };
258
+
259
+ this.operations.set(operationId, operation);
260
+ this.stats.pendingOperations++;
261
+
262
+ operation.status = 'processing';
263
+ const startTime = Date.now();
264
+
265
+ let result: TransactionResult;
266
+
267
+ if (existingIndexId && options.expectedVersion !== undefined) {
268
+ // Update existing index
269
+ result = await this.suiService.updateMemoryIndex(
270
+ existingIndexId,
271
+ userId,
272
+ options.expectedVersion,
273
+ indexBlobId,
274
+ graphBlobId,
275
+ {
276
+ enableBatching: options.enableBatching,
277
+ priority: this.mapPriority(options.priority)
278
+ }
279
+ );
280
+ } else {
281
+ // Create new index
282
+ result = await this.suiService.createMemoryIndex(
283
+ userId,
284
+ indexBlobId,
285
+ graphBlobId,
286
+ {
287
+ enableBatching: options.enableBatching,
288
+ priority: this.mapPriority(options.priority)
289
+ }
290
+ );
291
+ }
292
+
293
+ const processingTime = Date.now() - startTime;
294
+
295
+ if (result.success) {
296
+ operation.status = 'completed';
297
+ operation.result = result;
298
+ operation.completedAt = new Date();
299
+
300
+ // Create or update index record
301
+ const indexRecord: IndexOwnershipRecord = {
302
+ indexId: `index_${userId}_${Date.now()}`,
303
+ userId,
304
+ blockchainRecordId: result.objectId || existingIndexId || '',
305
+ indexBlobId,
306
+ graphBlobId,
307
+ version: existingIndexId ? (options.expectedVersion || 1) + 1 : 1,
308
+ createdAt: existingIndexId ? (this.indexCache.get(existingIndexId)?.createdAt || new Date()) : new Date(),
309
+ lastUpdated: new Date()
310
+ };
311
+
312
+ // Cache the record
313
+ if (this.config.enableCaching) {
314
+ this.indexCache.set(indexRecord.indexId, indexRecord);
315
+ }
316
+
317
+ // Update statistics
318
+ this.stats.successfulOperations++;
319
+ if (!existingIndexId) {
320
+ this.stats.indexRecords++;
321
+ this.stats.totalRecords++;
322
+ }
323
+ this.updateProcessingTimeStats(processingTime);
324
+
325
+ return indexRecord;
326
+
327
+ } else {
328
+ operation.status = 'failed';
329
+ operation.error = result.error;
330
+ this.stats.failedOperations++;
331
+
332
+ throw new Error(`Index operation failed: ${result.error}`);
333
+ }
334
+
335
+ } catch (error) {
336
+ const operation = this.operations.get(operationId);
337
+ if (operation) {
338
+ operation.status = 'failed';
339
+ operation.error = error instanceof Error ? error.message : String(error);
340
+ }
341
+
342
+ this.stats.failedOperations++;
343
+ this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
344
+
345
+ throw new Error(`Failed to create/update index: ${error instanceof Error ? error.message : String(error)}`);
346
+ } finally {
347
+ this.stats.pendingOperations = Math.max(0, this.stats.pendingOperations - 1);
348
+ }
349
+ }
350
+
351
+ // ==================== OWNERSHIP VERIFICATION ====================
352
+
353
+ /**
354
+ * Verify memory ownership
355
+ */
356
+ async verifyOwnership(
357
+ memoryId: string,
358
+ userId: string,
359
+ options: {
360
+ useCache?: boolean;
361
+ forceRefresh?: boolean;
362
+ } = {}
363
+ ): Promise<OwnershipVerification> {
364
+ const cacheKey = `${memoryId}_${userId}`;
365
+
366
+ // Check cache first
367
+ if (options.useCache && !options.forceRefresh) {
368
+ const cached = this.verificationCache.get(cacheKey);
369
+ if (cached && this.isCacheValid(cached.lastVerified)) {
370
+ return cached;
371
+ }
372
+ }
373
+
374
+ try {
375
+ // Get ownership record
376
+ const ownershipRecord = this.ownershipCache.get(memoryId);
377
+
378
+ if (!ownershipRecord) {
379
+ // Try to get from blockchain
380
+ const userRecords = await this.suiService.getUserMemoryRecords(userId);
381
+ const blockchainRecord = userRecords.find(r => r.id === memoryId);
382
+
383
+ const verification: OwnershipVerification = {
384
+ isOwner: blockchainRecord ? blockchainRecord.owner === userId : false,
385
+ ownerAddress: blockchainRecord?.owner || '',
386
+ recordExists: !!blockchainRecord,
387
+ lastVerified: new Date(),
388
+ blockchainRecord
389
+ };
390
+
391
+ // Cache the result
392
+ this.verificationCache.set(cacheKey, verification);
393
+ return verification;
394
+ }
395
+
396
+ // Verify ownership record
397
+ const verification: OwnershipVerification = {
398
+ isOwner: ownershipRecord.userId === userId,
399
+ ownerAddress: ownershipRecord.userId,
400
+ recordExists: true,
401
+ lastVerified: new Date()
402
+ };
403
+
404
+ // Cache the result
405
+ this.verificationCache.set(cacheKey, verification);
406
+ return verification;
407
+
408
+ } catch (error) {
409
+ console.error('Ownership verification failed:', error);
410
+
411
+ return {
412
+ isOwner: false,
413
+ ownerAddress: '',
414
+ recordExists: false,
415
+ lastVerified: new Date()
416
+ };
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Get user's memory ownership records
422
+ */
423
+ async getUserOwnershipRecords(userId: string): Promise<{
424
+ memoryRecords: MemoryOwnershipRecord[];
425
+ indexRecords: IndexOwnershipRecord[];
426
+ }> {
427
+ try {
428
+ // Get from cache
429
+ const memoryRecords = Array.from(this.ownershipCache.values())
430
+ .filter(record => record.userId === userId);
431
+
432
+ const indexRecords = Array.from(this.indexCache.values())
433
+ .filter(record => record.userId === userId);
434
+
435
+ // Get from blockchain if cache is empty or incomplete
436
+ if (memoryRecords.length === 0) {
437
+ const blockchainRecords = await this.suiService.getUserMemoryRecords(userId);
438
+
439
+ for (const bcRecord of blockchainRecords) {
440
+ const ownershipRecord: MemoryOwnershipRecord = {
441
+ memoryId: bcRecord.id,
442
+ userId: bcRecord.owner,
443
+ blockchainRecordId: bcRecord.id,
444
+ vectorId: bcRecord.vectorId,
445
+ blobId: bcRecord.blobId,
446
+ category: bcRecord.category,
447
+ createdAt: bcRecord.createdAt,
448
+ transactionDigest: '', // Not available from query
449
+ version: bcRecord.version
450
+ };
451
+
452
+ memoryRecords.push(ownershipRecord);
453
+
454
+ if (this.config.enableCaching) {
455
+ this.ownershipCache.set(bcRecord.id, ownershipRecord);
456
+ }
457
+ }
458
+ }
459
+
460
+ return { memoryRecords, indexRecords };
461
+
462
+ } catch (error) {
463
+ console.error('Failed to get user ownership records:', error);
464
+ return { memoryRecords: [], indexRecords: [] };
465
+ }
466
+ }
467
+
468
+ // ==================== BATCH OPERATIONS ====================
469
+
470
+ /**
471
+ * Process multiple memory records in batch
472
+ */
473
+ async createMemoryRecordsBatch(
474
+ memories: Array<{
475
+ memory: ProcessedMemory;
476
+ userId: string;
477
+ customMetadata?: Record<string, string>;
478
+ }>,
479
+ options: {
480
+ batchSize?: number;
481
+ onProgress?: (completed: number, total: number) => void;
482
+ } = {}
483
+ ): Promise<Array<MemoryOwnershipRecord | { error: string; memoryId: string }>> {
484
+ const batchSize = options.batchSize || 5;
485
+ const results: Array<MemoryOwnershipRecord | { error: string; memoryId: string }> = [];
486
+
487
+ // Process in batches
488
+ for (let i = 0; i < memories.length; i += batchSize) {
489
+ const batch = memories.slice(i, i + batchSize);
490
+
491
+ const batchPromises = batch.map(async ({ memory, userId, customMetadata }) => {
492
+ try {
493
+ return await this.createMemoryRecord(memory, userId, {
494
+ enableBatching: true,
495
+ customMetadata
496
+ });
497
+ } catch (error) {
498
+ return { error: error instanceof Error ? error.message : String(error), memoryId: memory.id };
499
+ }
500
+ });
501
+
502
+ const batchResults = await Promise.all(batchPromises);
503
+ results.push(...batchResults);
504
+
505
+ // Progress callback
506
+ if (options.onProgress) {
507
+ options.onProgress(i + batch.length, memories.length);
508
+ }
509
+ }
510
+
511
+ return results;
512
+ }
513
+
514
+ /**
515
+ * Flush pending blockchain operations
516
+ */
517
+ async flushPendingOperations(): Promise<TransactionResult[]> {
518
+ return await this.suiService.flushBatchQueue();
519
+ }
520
+
521
+ // ==================== ANALYTICS & MONITORING ====================
522
+
523
+ /**
524
+ * Get comprehensive blockchain statistics
525
+ */
526
+ getBlockchainStats(): BlockchainStats {
527
+ const suiStats = this.suiService.getStats();
528
+
529
+ return {
530
+ totalRecords: this.stats.totalRecords,
531
+ memoryRecords: this.stats.memoryRecords,
532
+ indexRecords: this.stats.indexRecords,
533
+ successfulOperations: this.stats.successfulOperations,
534
+ failedOperations: this.stats.failedOperations,
535
+ pendingOperations: this.stats.pendingOperations,
536
+ averageProcessingTime: this.stats.averageProcessingTime,
537
+ gasEfficiency: {
538
+ averageGasUsed: suiStats.averageGasUsed,
539
+ totalGasCost: suiStats.totalGasCost,
540
+ optimizationSavings: suiStats.batchedTransactions * 100 // Estimated savings
541
+ },
542
+ networkHealth: suiStats.networkHealth
543
+ };
544
+ }
545
+
546
+ /**
547
+ * Get operation status
548
+ */
549
+ getOperationStatus(operationId: string): BlockchainOperation | null {
550
+ return this.operations.get(operationId) || null;
551
+ }
552
+
553
+ /**
554
+ * Get pending operations
555
+ */
556
+ getPendingOperations(): BlockchainOperation[] {
557
+ return Array.from(this.operations.values())
558
+ .filter(op => op.status === 'pending' || op.status === 'processing');
559
+ }
560
+
561
+ /**
562
+ * Clear caches and reset
563
+ */
564
+ clearCaches(): void {
565
+ this.ownershipCache.clear();
566
+ this.indexCache.clear();
567
+ this.verificationCache.clear();
568
+ this.operations.clear();
569
+ }
570
+
571
+ // ==================== PRIVATE METHODS ====================
572
+
573
+ private convertToBlockchainMetadata(
574
+ memory: ProcessedMemory,
575
+ customMetadata?: Record<string, string>
576
+ ): MemoryMetadata {
577
+ return {
578
+ contentType: 'text/plain',
579
+ contentSize: memory.content ? memory.content.length : 0,
580
+ contentHash: this.generateContentHash(memory.content),
581
+ category: memory.category || 'general',
582
+ topic: memory.metadata?.topic || `Memory about ${memory.category || 'general'}`,
583
+ importance: memory.metadata?.importance || 5,
584
+ embeddingBlobId: memory.blobId || '',
585
+ embeddingDimension: memory.embedding ? memory.embedding.length : 3072,
586
+ createdTimestamp: memory.createdAt?.getTime() || Date.now(),
587
+ updatedTimestamp: memory.processedAt?.getTime() || memory.createdAt?.getTime() || Date.now(),
588
+ customMetadata: {
589
+ memoryId: memory.id,
590
+ embeddingModel: memory.embeddingModel || 'gemini',
591
+ ...customMetadata
592
+ }
593
+ };
594
+ }
595
+
596
+ private mapPriority(priority?: 'low' | 'normal' | 'high'): number {
597
+ const priorityMap = { low: 1, normal: 2, high: 3 };
598
+ return priorityMap[priority || 'normal'];
599
+ }
600
+
601
+ private generateContentHash(content: string): string {
602
+ // Simple hash - replace with proper hashing in production
603
+ let hash = 0;
604
+ for (let i = 0; i < content.length; i++) {
605
+ const char = content.charCodeAt(i);
606
+ hash = ((hash << 5) - hash) + char;
607
+ hash = hash & hash; // Convert to 32bit integer
608
+ }
609
+ return hash.toString(16);
610
+ }
611
+
612
+ private generateOperationId(): string {
613
+ return `op_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
614
+ }
615
+
616
+ private updateProcessingTimeStats(processingTime: number): void {
617
+ this.stats.totalProcessingTime += processingTime;
618
+ this.stats.averageProcessingTime =
619
+ this.stats.totalProcessingTime / this.stats.successfulOperations;
620
+ }
621
+
622
+ private isCacheValid(timestamp: Date): boolean {
623
+ const CACHE_TTL_MS = 10 * 60 * 1000; // 10 minutes
624
+ return Date.now() - timestamp.getTime() < CACHE_TTL_MS;
625
+ }
626
+ }
627
+
628
628
  export default BlockchainManager;