@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
|
@@ -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;
|