@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,318 +1,318 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @deprecated This service is deprecated and will be removed in the next major version.
|
|
3
|
-
* Use {@link CapabilityService} from `../services/CapabilityService` instead.
|
|
4
|
-
*
|
|
5
|
-
* The new capability-based architecture replaces HD wallet management with
|
|
6
|
-
* MemoryCap objects that follow the SEAL PrivateData pattern.
|
|
7
|
-
*
|
|
8
|
-
* Migration guide:
|
|
9
|
-
* - MainWalletService.deriveContextId() -> Use MemoryCap with appId directly
|
|
10
|
-
* - MainWalletService.createMainWallet() -> CapabilityService.create(appId)
|
|
11
|
-
* - MainWalletService.getMainWallet() -> CapabilityService.list()
|
|
12
|
-
*
|
|
13
|
-
* @see CapabilityService for the new implementation
|
|
14
|
-
*
|
|
15
|
-
* --------------------------------
|
|
16
|
-
* OLD DOCUMENTATION (for reference):
|
|
17
|
-
* --------------------------------
|
|
18
|
-
* MainWalletService - Core wallet identity and key management
|
|
19
|
-
*
|
|
20
|
-
* Manages the primary wallet identity for users, including:
|
|
21
|
-
* - Wallet creation and metadata management
|
|
22
|
-
* - Context ID derivation for app isolation
|
|
23
|
-
* - SEAL key rotation and session management
|
|
24
|
-
* - On-chain wallet registry integration
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
import { sha3_256 } from '@noble/hashes/sha3.js';
|
|
28
|
-
import { SuiClient } from '@mysten/sui/client';
|
|
29
|
-
import { Transaction } from '@mysten/sui/transactions';
|
|
30
|
-
// Use Web Crypto API (browser-compatible)
|
|
31
|
-
const randomBytes = (size: number): Uint8Array => {
|
|
32
|
-
const bytes = new Uint8Array(size);
|
|
33
|
-
crypto.getRandomValues(bytes);
|
|
34
|
-
return bytes;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
// Helper to convert Uint8Array to hex string
|
|
38
|
-
const bytesToHex = (bytes: Uint8Array): string => {
|
|
39
|
-
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
import {
|
|
43
|
-
MainWallet,
|
|
44
|
-
CreateMainWalletOptions,
|
|
45
|
-
DeriveContextIdOptions,
|
|
46
|
-
RotateKeysOptions,
|
|
47
|
-
RotateKeysResult,
|
|
48
|
-
DerivedContext
|
|
49
|
-
} from '../core/types/wallet';
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Configuration for MainWalletService
|
|
53
|
-
*/
|
|
54
|
-
export interface MainWalletServiceConfig {
|
|
55
|
-
/** Sui client instance */
|
|
56
|
-
suiClient: SuiClient;
|
|
57
|
-
/** Package ID for Move contracts */
|
|
58
|
-
packageId: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* MainWalletService handles core wallet identity management
|
|
63
|
-
* @deprecated Use {@link CapabilityService} instead
|
|
64
|
-
*/
|
|
65
|
-
export class MainWalletService {
|
|
66
|
-
private suiClient: SuiClient;
|
|
67
|
-
private packageId: string;
|
|
68
|
-
|
|
69
|
-
constructor(config: MainWalletServiceConfig) {
|
|
70
|
-
this.suiClient = config.suiClient;
|
|
71
|
-
this.packageId = config.packageId;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Get main wallet metadata for a user
|
|
76
|
-
* @param userAddress - User's Sui address
|
|
77
|
-
* @returns MainWallet metadata or null if not found
|
|
78
|
-
*/
|
|
79
|
-
async getMainWallet(userAddress: string): Promise<MainWallet | null> {
|
|
80
|
-
try {
|
|
81
|
-
// Query for main wallet object by owner
|
|
82
|
-
const response = await this.suiClient.getOwnedObjects({
|
|
83
|
-
owner: userAddress,
|
|
84
|
-
filter: {
|
|
85
|
-
StructType: `${this.packageId}::wallet::MainWallet`
|
|
86
|
-
},
|
|
87
|
-
options: {
|
|
88
|
-
showContent: true,
|
|
89
|
-
showType: true
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
if (response.data.length === 0) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Get the first (should be only) main wallet
|
|
98
|
-
const walletObject = response.data[0];
|
|
99
|
-
if (!walletObject.data?.content || walletObject.data.content.dataType !== 'moveObject') {
|
|
100
|
-
throw new Error('Invalid main wallet object structure');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const fields = walletObject.data.content.fields as any;
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
owner: userAddress,
|
|
107
|
-
walletId: walletObject.data.objectId,
|
|
108
|
-
createdAt: parseInt(fields.created_at || '0'),
|
|
109
|
-
salts: {
|
|
110
|
-
context: fields.context_salt || ''
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
} catch (error) {
|
|
114
|
-
console.error('Error fetching main wallet:', error);
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Create a new main wallet for a user
|
|
121
|
-
* @param options - Creation options
|
|
122
|
-
* @returns Created MainWallet metadata
|
|
123
|
-
*/
|
|
124
|
-
async createMainWallet(options: CreateMainWalletOptions): Promise<MainWallet> {
|
|
125
|
-
// Generate salts if not provided
|
|
126
|
-
const contextSalt = options.salts?.context || this.generateSalt();
|
|
127
|
-
|
|
128
|
-
// For now, return a simulated MainWallet since we need Move contract deployment first
|
|
129
|
-
// TODO: Implement actual on-chain wallet creation once wallet.move is deployed
|
|
130
|
-
const walletId = `wallet_${options.userAddress}_${Date.now()}`;
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
owner: options.userAddress,
|
|
134
|
-
walletId,
|
|
135
|
-
createdAt: Date.now(),
|
|
136
|
-
salts: {
|
|
137
|
-
context: contextSalt
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Derive a deterministic context ID for app isolation
|
|
144
|
-
* @param options - Derivation options
|
|
145
|
-
* @returns Deterministic context ID (hash only, for backward compatibility)
|
|
146
|
-
*/
|
|
147
|
-
async deriveContextId(options: DeriveContextIdOptions): Promise<string> {
|
|
148
|
-
let salt = options.salt;
|
|
149
|
-
|
|
150
|
-
// If no salt provided, get it from main wallet
|
|
151
|
-
if (!salt) {
|
|
152
|
-
const mainWallet = await this.getMainWallet(options.userAddress);
|
|
153
|
-
if (!mainWallet) {
|
|
154
|
-
throw new Error('Main wallet not found - create one first');
|
|
155
|
-
}
|
|
156
|
-
salt = mainWallet.salts.context;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Derive context ID: sha3_256(userAddress | appId | salt)
|
|
160
|
-
const input = `${options.userAddress}|${options.appId}|${salt}`;
|
|
161
|
-
const inputBytes = new TextEncoder().encode(input);
|
|
162
|
-
const hash = sha3_256(inputBytes);
|
|
163
|
-
|
|
164
|
-
return `0x${Array.from(hash).map(b => b.toString(16).padStart(2, '0')).join('')}`;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Get full context information (deterministic ID + object address if exists)
|
|
169
|
-
* @param userAddress - User's Sui address
|
|
170
|
-
* @param appId - Application identifier
|
|
171
|
-
* @returns DerivedContext with contextId and optional objectAddress
|
|
172
|
-
*/
|
|
173
|
-
async getContextInfo(
|
|
174
|
-
userAddress: string,
|
|
175
|
-
appId: string
|
|
176
|
-
): Promise<DerivedContext> {
|
|
177
|
-
// Derive deterministic ID
|
|
178
|
-
const contextId = await this.deriveContextId({ userAddress, appId });
|
|
179
|
-
|
|
180
|
-
// Check if context wallet object exists on-chain
|
|
181
|
-
const mainWallet = await this.getMainWallet(userAddress);
|
|
182
|
-
if (!mainWallet) {
|
|
183
|
-
return { contextId, appId, exists: false };
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Try to find context wallet as dynamic field
|
|
187
|
-
try {
|
|
188
|
-
const response = await this.suiClient.getDynamicFieldObject({
|
|
189
|
-
parentId: mainWallet.walletId,
|
|
190
|
-
name: {
|
|
191
|
-
type: '0x1::string::String',
|
|
192
|
-
value: appId
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
if (response.data) {
|
|
197
|
-
return {
|
|
198
|
-
contextId,
|
|
199
|
-
appId,
|
|
200
|
-
objectAddress: response.data.objectId,
|
|
201
|
-
exists: true
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
} catch (error) {
|
|
205
|
-
// Context not found as dynamic field
|
|
206
|
-
console.debug(`Context wallet not found for appId: ${appId}`);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return { contextId, appId, exists: false };
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Check if a context wallet exists on-chain
|
|
214
|
-
* @param userAddress - User's Sui address
|
|
215
|
-
* @param appId - Application identifier
|
|
216
|
-
* @returns True if context wallet exists as dynamic field
|
|
217
|
-
*/
|
|
218
|
-
async contextExists(
|
|
219
|
-
userAddress: string,
|
|
220
|
-
appId: string
|
|
221
|
-
): Promise<boolean> {
|
|
222
|
-
const contextInfo = await this.getContextInfo(userAddress, appId);
|
|
223
|
-
return contextInfo.exists;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Rotate SEAL session and backup keys for a user
|
|
228
|
-
* @param options - Rotation options
|
|
229
|
-
* @returns Result of key rotation
|
|
230
|
-
*/
|
|
231
|
-
async rotateKeys(options: RotateKeysOptions): Promise<RotateKeysResult> {
|
|
232
|
-
const { userAddress, sessionKeyTtlMin = 60 } = options;
|
|
233
|
-
|
|
234
|
-
try {
|
|
235
|
-
// TODO: Implement actual key rotation with SEAL service
|
|
236
|
-
// For now, return a simulated result
|
|
237
|
-
const sessionKeyId = `session_${userAddress}_${Date.now()}`;
|
|
238
|
-
const expiresAt = Date.now() + (sessionKeyTtlMin * 60 * 1000);
|
|
239
|
-
|
|
240
|
-
return {
|
|
241
|
-
sessionKeyId,
|
|
242
|
-
expiresAt,
|
|
243
|
-
backupKeyRotated: true
|
|
244
|
-
};
|
|
245
|
-
} catch (error) {
|
|
246
|
-
console.error('Error rotating keys:', error);
|
|
247
|
-
throw new Error(`Failed to rotate keys: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Check if a main wallet exists for a user
|
|
253
|
-
* @param userAddress - User's Sui address
|
|
254
|
-
* @returns True if main wallet exists
|
|
255
|
-
*/
|
|
256
|
-
async hasMainWallet(userAddress: string): Promise<boolean> {
|
|
257
|
-
const wallet = await this.getMainWallet(userAddress);
|
|
258
|
-
return wallet !== null;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Generate a cryptographically secure salt
|
|
263
|
-
* @returns Random salt as hex string
|
|
264
|
-
*/
|
|
265
|
-
private generateSalt(): string {
|
|
266
|
-
const bytes = randomBytes(32);
|
|
267
|
-
return bytesToHex(bytes);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Validate a user address format
|
|
272
|
-
* @param address - Address to validate
|
|
273
|
-
* @returns True if valid Sui address format
|
|
274
|
-
*/
|
|
275
|
-
private isValidSuiAddress(address: string): boolean {
|
|
276
|
-
return /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Get main wallet with validation
|
|
281
|
-
* @param userAddress - User's Sui address
|
|
282
|
-
* @returns MainWallet metadata
|
|
283
|
-
* @throws Error if wallet not found or address invalid
|
|
284
|
-
*/
|
|
285
|
-
async getMainWalletRequired(userAddress: string): Promise<MainWallet> {
|
|
286
|
-
if (!this.isValidSuiAddress(userAddress)) {
|
|
287
|
-
throw new Error(`Invalid Sui address format: ${userAddress}`);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const wallet = await this.getMainWallet(userAddress);
|
|
291
|
-
if (!wallet) {
|
|
292
|
-
throw new Error(`Main wallet not found for address: ${userAddress}`);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return wallet;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Create main wallet if it doesn't exist
|
|
300
|
-
* @param userAddress - User's Sui address
|
|
301
|
-
* @returns Existing or newly created MainWallet
|
|
302
|
-
*/
|
|
303
|
-
async ensureMainWallet(userAddress: string): Promise<MainWallet> {
|
|
304
|
-
if (!this.isValidSuiAddress(userAddress)) {
|
|
305
|
-
throw new Error(`Invalid Sui address format: ${userAddress}`);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const existing = await this.getMainWallet(userAddress);
|
|
309
|
-
if (existing) {
|
|
310
|
-
return existing;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Create new main wallet
|
|
314
|
-
return await this.createMainWallet({
|
|
315
|
-
userAddress
|
|
316
|
-
});
|
|
317
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated This service is deprecated and will be removed in the next major version.
|
|
3
|
+
* Use {@link CapabilityService} from `../services/CapabilityService` instead.
|
|
4
|
+
*
|
|
5
|
+
* The new capability-based architecture replaces HD wallet management with
|
|
6
|
+
* MemoryCap objects that follow the SEAL PrivateData pattern.
|
|
7
|
+
*
|
|
8
|
+
* Migration guide:
|
|
9
|
+
* - MainWalletService.deriveContextId() -> Use MemoryCap with appId directly
|
|
10
|
+
* - MainWalletService.createMainWallet() -> CapabilityService.create(appId)
|
|
11
|
+
* - MainWalletService.getMainWallet() -> CapabilityService.list()
|
|
12
|
+
*
|
|
13
|
+
* @see CapabilityService for the new implementation
|
|
14
|
+
*
|
|
15
|
+
* --------------------------------
|
|
16
|
+
* OLD DOCUMENTATION (for reference):
|
|
17
|
+
* --------------------------------
|
|
18
|
+
* MainWalletService - Core wallet identity and key management
|
|
19
|
+
*
|
|
20
|
+
* Manages the primary wallet identity for users, including:
|
|
21
|
+
* - Wallet creation and metadata management
|
|
22
|
+
* - Context ID derivation for app isolation
|
|
23
|
+
* - SEAL key rotation and session management
|
|
24
|
+
* - On-chain wallet registry integration
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { sha3_256 } from '@noble/hashes/sha3.js';
|
|
28
|
+
import { SuiClient } from '@mysten/sui/client';
|
|
29
|
+
import { Transaction } from '@mysten/sui/transactions';
|
|
30
|
+
// Use Web Crypto API (browser-compatible)
|
|
31
|
+
const randomBytes = (size: number): Uint8Array => {
|
|
32
|
+
const bytes = new Uint8Array(size);
|
|
33
|
+
crypto.getRandomValues(bytes);
|
|
34
|
+
return bytes;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Helper to convert Uint8Array to hex string
|
|
38
|
+
const bytesToHex = (bytes: Uint8Array): string => {
|
|
39
|
+
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
import {
|
|
43
|
+
MainWallet,
|
|
44
|
+
CreateMainWalletOptions,
|
|
45
|
+
DeriveContextIdOptions,
|
|
46
|
+
RotateKeysOptions,
|
|
47
|
+
RotateKeysResult,
|
|
48
|
+
DerivedContext
|
|
49
|
+
} from '../core/types/wallet';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Configuration for MainWalletService
|
|
53
|
+
*/
|
|
54
|
+
export interface MainWalletServiceConfig {
|
|
55
|
+
/** Sui client instance */
|
|
56
|
+
suiClient: SuiClient;
|
|
57
|
+
/** Package ID for Move contracts */
|
|
58
|
+
packageId: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* MainWalletService handles core wallet identity management
|
|
63
|
+
* @deprecated Use {@link CapabilityService} instead
|
|
64
|
+
*/
|
|
65
|
+
export class MainWalletService {
|
|
66
|
+
private suiClient: SuiClient;
|
|
67
|
+
private packageId: string;
|
|
68
|
+
|
|
69
|
+
constructor(config: MainWalletServiceConfig) {
|
|
70
|
+
this.suiClient = config.suiClient;
|
|
71
|
+
this.packageId = config.packageId;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get main wallet metadata for a user
|
|
76
|
+
* @param userAddress - User's Sui address
|
|
77
|
+
* @returns MainWallet metadata or null if not found
|
|
78
|
+
*/
|
|
79
|
+
async getMainWallet(userAddress: string): Promise<MainWallet | null> {
|
|
80
|
+
try {
|
|
81
|
+
// Query for main wallet object by owner
|
|
82
|
+
const response = await this.suiClient.getOwnedObjects({
|
|
83
|
+
owner: userAddress,
|
|
84
|
+
filter: {
|
|
85
|
+
StructType: `${this.packageId}::wallet::MainWallet`
|
|
86
|
+
},
|
|
87
|
+
options: {
|
|
88
|
+
showContent: true,
|
|
89
|
+
showType: true
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (response.data.length === 0) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Get the first (should be only) main wallet
|
|
98
|
+
const walletObject = response.data[0];
|
|
99
|
+
if (!walletObject.data?.content || walletObject.data.content.dataType !== 'moveObject') {
|
|
100
|
+
throw new Error('Invalid main wallet object structure');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const fields = walletObject.data.content.fields as any;
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
owner: userAddress,
|
|
107
|
+
walletId: walletObject.data.objectId,
|
|
108
|
+
createdAt: parseInt(fields.created_at || '0'),
|
|
109
|
+
salts: {
|
|
110
|
+
context: fields.context_salt || ''
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error('Error fetching main wallet:', error);
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Create a new main wallet for a user
|
|
121
|
+
* @param options - Creation options
|
|
122
|
+
* @returns Created MainWallet metadata
|
|
123
|
+
*/
|
|
124
|
+
async createMainWallet(options: CreateMainWalletOptions): Promise<MainWallet> {
|
|
125
|
+
// Generate salts if not provided
|
|
126
|
+
const contextSalt = options.salts?.context || this.generateSalt();
|
|
127
|
+
|
|
128
|
+
// For now, return a simulated MainWallet since we need Move contract deployment first
|
|
129
|
+
// TODO: Implement actual on-chain wallet creation once wallet.move is deployed
|
|
130
|
+
const walletId = `wallet_${options.userAddress}_${Date.now()}`;
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
owner: options.userAddress,
|
|
134
|
+
walletId,
|
|
135
|
+
createdAt: Date.now(),
|
|
136
|
+
salts: {
|
|
137
|
+
context: contextSalt
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Derive a deterministic context ID for app isolation
|
|
144
|
+
* @param options - Derivation options
|
|
145
|
+
* @returns Deterministic context ID (hash only, for backward compatibility)
|
|
146
|
+
*/
|
|
147
|
+
async deriveContextId(options: DeriveContextIdOptions): Promise<string> {
|
|
148
|
+
let salt = options.salt;
|
|
149
|
+
|
|
150
|
+
// If no salt provided, get it from main wallet
|
|
151
|
+
if (!salt) {
|
|
152
|
+
const mainWallet = await this.getMainWallet(options.userAddress);
|
|
153
|
+
if (!mainWallet) {
|
|
154
|
+
throw new Error('Main wallet not found - create one first');
|
|
155
|
+
}
|
|
156
|
+
salt = mainWallet.salts.context;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Derive context ID: sha3_256(userAddress | appId | salt)
|
|
160
|
+
const input = `${options.userAddress}|${options.appId}|${salt}`;
|
|
161
|
+
const inputBytes = new TextEncoder().encode(input);
|
|
162
|
+
const hash = sha3_256(inputBytes);
|
|
163
|
+
|
|
164
|
+
return `0x${Array.from(hash).map(b => b.toString(16).padStart(2, '0')).join('')}`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get full context information (deterministic ID + object address if exists)
|
|
169
|
+
* @param userAddress - User's Sui address
|
|
170
|
+
* @param appId - Application identifier
|
|
171
|
+
* @returns DerivedContext with contextId and optional objectAddress
|
|
172
|
+
*/
|
|
173
|
+
async getContextInfo(
|
|
174
|
+
userAddress: string,
|
|
175
|
+
appId: string
|
|
176
|
+
): Promise<DerivedContext> {
|
|
177
|
+
// Derive deterministic ID
|
|
178
|
+
const contextId = await this.deriveContextId({ userAddress, appId });
|
|
179
|
+
|
|
180
|
+
// Check if context wallet object exists on-chain
|
|
181
|
+
const mainWallet = await this.getMainWallet(userAddress);
|
|
182
|
+
if (!mainWallet) {
|
|
183
|
+
return { contextId, appId, exists: false };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Try to find context wallet as dynamic field
|
|
187
|
+
try {
|
|
188
|
+
const response = await this.suiClient.getDynamicFieldObject({
|
|
189
|
+
parentId: mainWallet.walletId,
|
|
190
|
+
name: {
|
|
191
|
+
type: '0x1::string::String',
|
|
192
|
+
value: appId
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
if (response.data) {
|
|
197
|
+
return {
|
|
198
|
+
contextId,
|
|
199
|
+
appId,
|
|
200
|
+
objectAddress: response.data.objectId,
|
|
201
|
+
exists: true
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
} catch (error) {
|
|
205
|
+
// Context not found as dynamic field
|
|
206
|
+
console.debug(`Context wallet not found for appId: ${appId}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return { contextId, appId, exists: false };
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Check if a context wallet exists on-chain
|
|
214
|
+
* @param userAddress - User's Sui address
|
|
215
|
+
* @param appId - Application identifier
|
|
216
|
+
* @returns True if context wallet exists as dynamic field
|
|
217
|
+
*/
|
|
218
|
+
async contextExists(
|
|
219
|
+
userAddress: string,
|
|
220
|
+
appId: string
|
|
221
|
+
): Promise<boolean> {
|
|
222
|
+
const contextInfo = await this.getContextInfo(userAddress, appId);
|
|
223
|
+
return contextInfo.exists;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Rotate SEAL session and backup keys for a user
|
|
228
|
+
* @param options - Rotation options
|
|
229
|
+
* @returns Result of key rotation
|
|
230
|
+
*/
|
|
231
|
+
async rotateKeys(options: RotateKeysOptions): Promise<RotateKeysResult> {
|
|
232
|
+
const { userAddress, sessionKeyTtlMin = 60 } = options;
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
// TODO: Implement actual key rotation with SEAL service
|
|
236
|
+
// For now, return a simulated result
|
|
237
|
+
const sessionKeyId = `session_${userAddress}_${Date.now()}`;
|
|
238
|
+
const expiresAt = Date.now() + (sessionKeyTtlMin * 60 * 1000);
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
sessionKeyId,
|
|
242
|
+
expiresAt,
|
|
243
|
+
backupKeyRotated: true
|
|
244
|
+
};
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error('Error rotating keys:', error);
|
|
247
|
+
throw new Error(`Failed to rotate keys: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Check if a main wallet exists for a user
|
|
253
|
+
* @param userAddress - User's Sui address
|
|
254
|
+
* @returns True if main wallet exists
|
|
255
|
+
*/
|
|
256
|
+
async hasMainWallet(userAddress: string): Promise<boolean> {
|
|
257
|
+
const wallet = await this.getMainWallet(userAddress);
|
|
258
|
+
return wallet !== null;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Generate a cryptographically secure salt
|
|
263
|
+
* @returns Random salt as hex string
|
|
264
|
+
*/
|
|
265
|
+
private generateSalt(): string {
|
|
266
|
+
const bytes = randomBytes(32);
|
|
267
|
+
return bytesToHex(bytes);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Validate a user address format
|
|
272
|
+
* @param address - Address to validate
|
|
273
|
+
* @returns True if valid Sui address format
|
|
274
|
+
*/
|
|
275
|
+
private isValidSuiAddress(address: string): boolean {
|
|
276
|
+
return /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Get main wallet with validation
|
|
281
|
+
* @param userAddress - User's Sui address
|
|
282
|
+
* @returns MainWallet metadata
|
|
283
|
+
* @throws Error if wallet not found or address invalid
|
|
284
|
+
*/
|
|
285
|
+
async getMainWalletRequired(userAddress: string): Promise<MainWallet> {
|
|
286
|
+
if (!this.isValidSuiAddress(userAddress)) {
|
|
287
|
+
throw new Error(`Invalid Sui address format: ${userAddress}`);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const wallet = await this.getMainWallet(userAddress);
|
|
291
|
+
if (!wallet) {
|
|
292
|
+
throw new Error(`Main wallet not found for address: ${userAddress}`);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return wallet;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Create main wallet if it doesn't exist
|
|
300
|
+
* @param userAddress - User's Sui address
|
|
301
|
+
* @returns Existing or newly created MainWallet
|
|
302
|
+
*/
|
|
303
|
+
async ensureMainWallet(userAddress: string): Promise<MainWallet> {
|
|
304
|
+
if (!this.isValidSuiAddress(userAddress)) {
|
|
305
|
+
throw new Error(`Invalid Sui address format: ${userAddress}`);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const existing = await this.getMainWallet(userAddress);
|
|
309
|
+
if (existing) {
|
|
310
|
+
return existing;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Create new main wallet
|
|
314
|
+
return await this.createMainWallet({
|
|
315
|
+
userAddress
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
318
|
}
|