@cmdoss/memwal-sdk 0.8.0 → 0.9.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/README.md +389 -132
- package/dist/client/SimplePDWClient.d.ts +60 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +73 -5
- package/dist/client/SimplePDWClient.js.map +1 -1
- package/dist/client/namespaces/IndexNamespace.d.ts +1 -1
- package/dist/client/namespaces/IndexNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/IndexNamespace.js +7 -4
- package/dist/client/namespaces/IndexNamespace.js.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +41 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +126 -9
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/AdvancedNamespace.d.ts +215 -0
- package/dist/client/namespaces/consolidated/AdvancedNamespace.d.ts.map +1 -0
- package/dist/client/namespaces/consolidated/AdvancedNamespace.js +214 -0
- package/dist/client/namespaces/consolidated/AdvancedNamespace.js.map +1 -0
- package/dist/client/namespaces/consolidated/index.d.ts +1 -0
- package/dist/client/namespaces/consolidated/index.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/index.js +1 -0
- package/dist/client/namespaces/consolidated/index.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +9 -4
- package/dist/config/defaults.js.map +1 -1
- package/dist/core/types/index.d.ts +4 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js.map +1 -1
- package/dist/infrastructure/walrus/WalrusStorageService.d.ts +6 -0
- package/dist/infrastructure/walrus/WalrusStorageService.d.ts.map +1 -1
- package/dist/infrastructure/walrus/WalrusStorageService.js +23 -4
- package/dist/infrastructure/walrus/WalrusStorageService.js.map +1 -1
- package/dist/services/EmbeddingService.d.ts +9 -0
- package/dist/services/EmbeddingService.d.ts.map +1 -1
- package/dist/services/EmbeddingService.js +31 -10
- package/dist/services/EmbeddingService.js.map +1 -1
- package/dist/services/MemoryIndexService.d.ts +2 -0
- package/dist/services/MemoryIndexService.d.ts.map +1 -1
- package/dist/services/MemoryIndexService.js +11 -4
- package/dist/services/MemoryIndexService.js.map +1 -1
- package/dist/services/VectorService.js +1 -1
- package/dist/services/VectorService.js.map +1 -1
- package/dist/vector/BrowserHnswIndexService.js +1 -1
- package/dist/vector/BrowserHnswIndexService.js.map +1 -1
- package/dist/vector/HnswWasmService.js +1 -1
- package/dist/vector/HnswWasmService.js.map +1 -1
- package/dist/vector/NodeHnswService.js +1 -1
- package/dist/vector/NodeHnswService.js.map +1 -1
- package/package.json +1 -1
- package/src/client/SimplePDWClient.ts +86 -6
- package/src/client/namespaces/IndexNamespace.ts +7 -4
- package/src/client/namespaces/MemoryNamespace.ts +156 -9
- package/src/client/namespaces/consolidated/AdvancedNamespace.ts +264 -0
- package/src/client/namespaces/consolidated/index.ts +2 -0
- package/src/config/defaults.ts +9 -4
- package/src/core/types/index.ts +4 -0
- package/src/infrastructure/walrus/WalrusStorageService.ts +29 -4
- package/src/services/EmbeddingService.ts +35 -10
- package/src/services/MemoryIndexService.ts +11 -5
- package/src/services/VectorService.ts +1 -1
- package/src/vector/BrowserHnswIndexService.ts +1 -1
- package/src/vector/HnswWasmService.ts +1 -1
- package/src/vector/NodeHnswService.ts +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
**MemWal** (Memory + Walrus) - TypeScript SDK for decentralized memory storage on Sui blockchain with Walrus.
|
|
7
7
|
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
| Feature | Description |
|
|
11
|
+
|---------|-------------|
|
|
12
|
+
| **Memory CRUD** | Create, read, search, delete memories on Sui + Walrus |
|
|
13
|
+
| **Unified Search** | `pdw.memory.search()` - auto-embeds query and searches |
|
|
14
|
+
| **SEAL Encryption** | Identity-based encryption (enabled by default) |
|
|
15
|
+
| **Vector Search** | Fast HNSW search (768 dimensions default) |
|
|
16
|
+
| **AI Classification** | Auto-categorize memories (fact, event, preference, etc.) |
|
|
17
|
+
| **Batch Upload** | ~90% gas savings with Quilt batching |
|
|
18
|
+
| **Knowledge Graph** | Entity and relationship extraction |
|
|
19
|
+
|
|
8
20
|
## Installation
|
|
9
21
|
|
|
10
22
|
```bash
|
|
@@ -31,17 +43,19 @@ const pdw = new SimplePDWClient({
|
|
|
31
43
|
embedding: {
|
|
32
44
|
provider: 'openrouter',
|
|
33
45
|
apiKey: process.env.OPENROUTER_API_KEY!,
|
|
46
|
+
dimensions: 768 // Default: 768 (fast), 1536, or 3072 (highest quality)
|
|
34
47
|
}
|
|
35
48
|
});
|
|
36
49
|
|
|
37
50
|
await pdw.ready();
|
|
38
51
|
|
|
39
|
-
// Create memory
|
|
52
|
+
// Create memory (auto: embed, classify, encrypt, upload, register, index)
|
|
40
53
|
const memory = await pdw.memory.create('I work at CommandOSS as a developer');
|
|
41
54
|
console.log('Memory ID:', memory.id);
|
|
42
55
|
|
|
43
|
-
// Search memories
|
|
44
|
-
const results = await pdw.search
|
|
56
|
+
// Search memories (NEW: unified search API)
|
|
57
|
+
const results = await pdw.memory.search('work experience', { limit: 5 });
|
|
58
|
+
console.log('Found:', results.length, 'memories');
|
|
45
59
|
```
|
|
46
60
|
|
|
47
61
|
### Browser (with dapp-kit + Slush/Sui Wallet)
|
|
@@ -72,232 +86,475 @@ function MyComponent() {
|
|
|
72
86
|
network: 'testnet',
|
|
73
87
|
userAddress: account.address,
|
|
74
88
|
sui: { packageId: process.env.NEXT_PUBLIC_PACKAGE_ID! },
|
|
89
|
+
embedding: {
|
|
90
|
+
provider: 'openrouter',
|
|
91
|
+
apiKey: process.env.NEXT_PUBLIC_OPENROUTER_API_KEY!,
|
|
92
|
+
dimensions: 768
|
|
93
|
+
},
|
|
75
94
|
features: { enableLocalIndexing: false }, // Disable for browser
|
|
76
95
|
});
|
|
77
96
|
|
|
97
|
+
await pdw.ready();
|
|
98
|
+
|
|
78
99
|
// Create memory - wallet popup appears for signing
|
|
79
100
|
const memory = await pdw.memory.create('Hello from browser!');
|
|
101
|
+
|
|
102
|
+
// Search memories
|
|
103
|
+
const results = await pdw.memory.search('hello', { limit: 5 });
|
|
80
104
|
};
|
|
81
105
|
}
|
|
82
106
|
```
|
|
83
107
|
|
|
84
|
-
##
|
|
108
|
+
## API Reference
|
|
85
109
|
|
|
86
|
-
|
|
87
|
-
|---------|-------------|
|
|
88
|
-
| Memory CRUD | Create, read, update, delete memories on Sui + Walrus |
|
|
89
|
-
| Vector Search | Semantic search with HNSW (3072 dimensions) |
|
|
90
|
-
| AI Classification | Auto-categorize memories (fact, event, preference, etc.) |
|
|
91
|
-
| SEAL Encryption | Optional identity-based encryption |
|
|
92
|
-
| Batch Upload | ~90% gas savings with Quilt batching |
|
|
93
|
-
| Knowledge Graph | Entity and relationship extraction |
|
|
110
|
+
### Core Namespaces
|
|
94
111
|
|
|
95
|
-
|
|
112
|
+
The SDK provides 5 core namespaces for common operations:
|
|
96
113
|
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
114
|
+
```typescript
|
|
115
|
+
pdw.memory // Create, get, search, list, delete memories
|
|
116
|
+
pdw.ai // Embed, classify, extract commands
|
|
117
|
+
pdw.index // HNSW index management
|
|
118
|
+
pdw.wallet // Wallet address and balance info
|
|
119
|
+
pdw.advanced // Power user features (graph, analytics, etc.)
|
|
120
|
+
```
|
|
101
121
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
### `pdw.memory` - Memory Operations
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// CREATE - handles everything internally (embed, encrypt, upload, register, index)
|
|
126
|
+
const memory = await pdw.memory.create(content, {
|
|
127
|
+
category?: string, // Auto-classify if not provided
|
|
128
|
+
importance?: number, // Auto-score if not provided (1-10)
|
|
129
|
+
embedding?: number[], // Auto-generate if not provided
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// CREATE BATCH - upload multiple memories efficiently
|
|
133
|
+
const memories = await pdw.memory.createBatch([
|
|
134
|
+
{ content: 'Memory 1', category: 'fact' },
|
|
135
|
+
{ content: 'Memory 2', category: 'preference' }
|
|
136
|
+
]);
|
|
137
|
+
|
|
138
|
+
// SEARCH - unified semantic search (auto-embeds query)
|
|
139
|
+
const results = await pdw.memory.search(query, {
|
|
140
|
+
limit?: number, // Max results (default: 10)
|
|
141
|
+
threshold?: number, // Min similarity 0-1 (default: 0.7)
|
|
142
|
+
category?: string, // Filter by category
|
|
143
|
+
includeContent?: boolean // Include decrypted content (default: true)
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// GET - retrieve by ID (auto-decrypts)
|
|
147
|
+
const memory = await pdw.memory.get(memoryId);
|
|
148
|
+
|
|
149
|
+
// LIST - list all memories with filters
|
|
150
|
+
const memories = await pdw.memory.list({
|
|
151
|
+
category?: string,
|
|
152
|
+
limit?: number,
|
|
153
|
+
offset?: number
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// DELETE
|
|
157
|
+
await pdw.memory.delete(memoryId);
|
|
158
|
+
await pdw.memory.deleteBatch([id1, id2, id3]);
|
|
105
159
|
```
|
|
106
160
|
|
|
107
|
-
|
|
161
|
+
### `pdw.ai` - AI Operations
|
|
108
162
|
|
|
109
163
|
```typescript
|
|
110
|
-
//
|
|
111
|
-
await pdw.
|
|
112
|
-
await pdw.
|
|
113
|
-
await pdw.memory.get(id);
|
|
114
|
-
await pdw.memory.delete(id);
|
|
115
|
-
|
|
116
|
-
// Search
|
|
117
|
-
await pdw.search.vector(query, { limit });
|
|
118
|
-
await pdw.search.byCategory('fact');
|
|
119
|
-
await pdw.search.hybrid(query, { category });
|
|
120
|
-
|
|
121
|
-
// AI
|
|
122
|
-
await pdw.ai.embed(text);
|
|
123
|
-
await pdw.ai.classify(content);
|
|
124
|
-
await pdw.ai.shouldSave(content);
|
|
164
|
+
// Generate embeddings
|
|
165
|
+
const embedding = await pdw.ai.embed(text);
|
|
166
|
+
const embeddings = await pdw.ai.embedBatch([text1, text2]);
|
|
125
167
|
|
|
126
|
-
//
|
|
127
|
-
await pdw.
|
|
168
|
+
// Classify content
|
|
169
|
+
const { category, importance } = await pdw.ai.classify(content);
|
|
170
|
+
|
|
171
|
+
// Extract memory commands from user input
|
|
172
|
+
const memories = pdw.ai.extractMultipleMemories(userMessage);
|
|
173
|
+
// Input: "remember I like pizza and my name is John"
|
|
174
|
+
// Output: ["I like pizza", "my name is John"]
|
|
175
|
+
|
|
176
|
+
// Check if content should be saved as memory
|
|
177
|
+
const shouldSave = await pdw.ai.shouldSave(content);
|
|
128
178
|
```
|
|
129
179
|
|
|
130
|
-
|
|
180
|
+
### `pdw.index` - HNSW Index Management
|
|
131
181
|
|
|
132
|
-
|
|
182
|
+
```typescript
|
|
183
|
+
// Add vector to index
|
|
184
|
+
await pdw.index.add(spaceId, vectorId, vector, {
|
|
185
|
+
content: string,
|
|
186
|
+
blobId: string,
|
|
187
|
+
category: string,
|
|
188
|
+
importance: number,
|
|
189
|
+
isEncrypted: boolean,
|
|
190
|
+
forceStoreContent: boolean // Store content even when encrypted (for RAG)
|
|
191
|
+
});
|
|
133
192
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
193
|
+
// Search vectors
|
|
194
|
+
const results = await pdw.index.search(spaceId, queryVector, {
|
|
195
|
+
k: 10,
|
|
196
|
+
threshold: 0.7
|
|
197
|
+
});
|
|
138
198
|
|
|
139
|
-
|
|
199
|
+
// Get index stats
|
|
200
|
+
const stats = pdw.index.getStats(spaceId);
|
|
140
201
|
|
|
141
|
-
|
|
202
|
+
// Rebuild index from blockchain
|
|
203
|
+
await pdw.index.rebuild(userAddress);
|
|
142
204
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
205
|
+
// Clear index
|
|
206
|
+
await pdw.index.clear(spaceId);
|
|
207
|
+
|
|
208
|
+
// Flush to disk
|
|
209
|
+
await pdw.index.flush(spaceId);
|
|
146
210
|
```
|
|
147
211
|
|
|
148
|
-
|
|
149
|
-
<summary>Build tools installation</summary>
|
|
212
|
+
### `pdw.wallet` - Wallet Information
|
|
150
213
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
| macOS | `xcode-select --install` |
|
|
155
|
-
| Linux | `sudo apt-get install build-essential python3` |
|
|
214
|
+
```typescript
|
|
215
|
+
// Get wallet address
|
|
216
|
+
const address = pdw.wallet.address;
|
|
156
217
|
|
|
157
|
-
|
|
218
|
+
// Get SUI balance
|
|
219
|
+
const balance = await pdw.wallet.balance();
|
|
220
|
+
|
|
221
|
+
// Get memory count
|
|
222
|
+
const count = await pdw.wallet.memoryCount();
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### `pdw.advanced` - Power User Features
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Knowledge Graph
|
|
229
|
+
const graph = await pdw.advanced.graph.extract(content);
|
|
230
|
+
// Returns: { entities: [...], relationships: [...] }
|
|
231
|
+
|
|
232
|
+
// Analytics
|
|
233
|
+
const insights = await pdw.advanced.analytics.getInsights();
|
|
234
|
+
|
|
235
|
+
// Manual encryption/decryption
|
|
236
|
+
const encrypted = await pdw.advanced.encryption.encrypt(data);
|
|
237
|
+
const decrypted = await pdw.advanced.encryption.decrypt(encrypted);
|
|
238
|
+
|
|
239
|
+
// Permissions
|
|
240
|
+
await pdw.advanced.permissions.grant(memoryId, targetAddress);
|
|
241
|
+
await pdw.advanced.permissions.revoke(memoryId, targetAddress);
|
|
242
|
+
|
|
243
|
+
// Transaction building (low-level)
|
|
244
|
+
const tx = pdw.advanced.blockchain.buildCreateMemoryTx(params);
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Legacy Search API (Deprecated)
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
// Still works but deprecated - use pdw.memory.search() instead
|
|
251
|
+
await pdw.search.vector(query, { limit }); // -> pdw.memory.search()
|
|
252
|
+
await pdw.search.byCategory('fact'); // -> pdw.memory.list({ category: 'fact' })
|
|
253
|
+
await pdw.search.hybrid(query, { category }); // -> pdw.memory.search(query, { category })
|
|
254
|
+
```
|
|
158
255
|
|
|
159
256
|
## Configuration
|
|
160
257
|
|
|
161
|
-
###
|
|
258
|
+
### Full Configuration
|
|
162
259
|
|
|
163
260
|
```typescript
|
|
164
261
|
const pdw = new SimplePDWClient({
|
|
165
|
-
|
|
166
|
-
|
|
262
|
+
// Required
|
|
263
|
+
signer: keypair, // Sui keypair or wallet adapter
|
|
264
|
+
network: 'testnet', // 'testnet' | 'mainnet' | 'devnet'
|
|
167
265
|
|
|
168
266
|
// Embedding configuration (required for AI features)
|
|
169
267
|
embedding: {
|
|
170
|
-
provider: 'openrouter',
|
|
268
|
+
provider: 'openrouter', // 'google' | 'openai' | 'openrouter' | 'cohere'
|
|
171
269
|
apiKey: process.env.OPENROUTER_API_KEY,
|
|
172
|
-
modelName: 'google/
|
|
173
|
-
dimensions:
|
|
270
|
+
modelName: 'google/text-embedding-004', // Optional: defaults per provider
|
|
271
|
+
dimensions: 768 // Optional: 768 (default), 1536, or 3072
|
|
174
272
|
},
|
|
175
273
|
|
|
176
274
|
// Optional: Sui configuration
|
|
177
275
|
sui: {
|
|
178
|
-
packageId: '0x...',
|
|
179
|
-
rpcUrl: 'https://...',
|
|
276
|
+
packageId: '0x...', // Default: from env PACKAGE_ID
|
|
277
|
+
rpcUrl: 'https://...', // Default: from network
|
|
180
278
|
},
|
|
181
279
|
|
|
182
280
|
// Optional: Walrus configuration
|
|
183
281
|
walrus: {
|
|
184
|
-
|
|
185
|
-
|
|
282
|
+
aggregatorUrl: 'https://aggregator.walrus-testnet.walrus.space',
|
|
283
|
+
publisherUrl: 'https://publisher.walrus-testnet.walrus.space',
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
// Optional: AI configuration
|
|
287
|
+
ai: {
|
|
288
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
289
|
+
chatModel: 'google/gemini-2.5-flash',
|
|
186
290
|
},
|
|
187
291
|
|
|
188
292
|
// Optional: Feature flags
|
|
189
293
|
features: {
|
|
190
|
-
enableEncryption: true,
|
|
191
|
-
enableLocalIndexing: true,
|
|
192
|
-
enableKnowledgeGraph: true
|
|
294
|
+
enableEncryption: true, // Default: true (SEAL encryption)
|
|
295
|
+
enableLocalIndexing: true, // Default: true (HNSW vector search)
|
|
296
|
+
enableKnowledgeGraph: true // Default: true (entity extraction)
|
|
297
|
+
},
|
|
298
|
+
|
|
299
|
+
// Optional: Encryption configuration
|
|
300
|
+
encryption: {
|
|
301
|
+
enabled: true,
|
|
302
|
+
keyServers: ['0x...', '0x...'], // Default: testnet key servers
|
|
303
|
+
threshold: 2, // M of N key servers required
|
|
304
|
+
accessRegistryId: '0x...'
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
// Optional: Index backup to Walrus (cloud sync)
|
|
308
|
+
indexBackup: {
|
|
309
|
+
enabled: true,
|
|
310
|
+
aggregatorUrl: 'https://...',
|
|
311
|
+
publisherUrl: 'https://...',
|
|
312
|
+
autoSync: false,
|
|
313
|
+
epochs: 3
|
|
193
314
|
}
|
|
194
315
|
});
|
|
195
316
|
```
|
|
196
317
|
|
|
197
|
-
###
|
|
318
|
+
### Environment Variables
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
# Required
|
|
322
|
+
SUI_PRIVATE_KEY=suiprivkey1...
|
|
323
|
+
PACKAGE_ID=0x...
|
|
324
|
+
|
|
325
|
+
# Embedding (at least one API key required)
|
|
326
|
+
EMBEDDING_PROVIDER=openrouter # google, openai, openrouter, cohere
|
|
327
|
+
EMBEDDING_API_KEY= # Falls back to provider-specific keys
|
|
328
|
+
EMBEDDING_MODEL= # Optional: override default model
|
|
329
|
+
EMBEDDING_DIMENSIONS=768 # 768 (default), 1536, 3072
|
|
330
|
+
|
|
331
|
+
# Provider-specific API keys (fallback)
|
|
332
|
+
OPENROUTER_API_KEY=sk-or-v1-...
|
|
333
|
+
GEMINI_API_KEY=...
|
|
334
|
+
OPENAI_API_KEY=sk-...
|
|
335
|
+
COHERE_API_KEY=...
|
|
336
|
+
|
|
337
|
+
# Walrus (optional - defaults to testnet)
|
|
338
|
+
WALRUS_NETWORK=testnet
|
|
339
|
+
WALRUS_AGGREGATOR=https://aggregator.walrus-testnet.walrus.space
|
|
340
|
+
WALRUS_PUBLISHER=https://publisher.walrus-testnet.walrus.space
|
|
341
|
+
|
|
342
|
+
# SEAL Encryption (optional - defaults configured)
|
|
343
|
+
ENABLE_ENCRYPTION=true
|
|
344
|
+
SEAL_KEY_SERVERS=0xKEY1,0xKEY2
|
|
345
|
+
SEAL_THRESHOLD=2
|
|
346
|
+
ACCESS_REGISTRY_ID=0x...
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### Embedding Providers
|
|
198
350
|
|
|
199
|
-
|
|
351
|
+
| Provider | Model Default | Dimensions | API Key |
|
|
352
|
+
|----------|---------------|------------|---------|
|
|
353
|
+
| `openrouter` | `google/text-embedding-004` | 768 | `OPENROUTER_API_KEY` |
|
|
354
|
+
| `google` | `text-embedding-004` | 768 | `GEMINI_API_KEY` |
|
|
355
|
+
| `openai` | `text-embedding-3-small` | 1536 | `OPENAI_API_KEY` |
|
|
356
|
+
| `cohere` | `embed-english-v3.0` | 1024 | `COHERE_API_KEY` |
|
|
357
|
+
|
|
358
|
+
**Dimensions Trade-offs:**
|
|
359
|
+
- **768** (default): Fast embedding + small storage + fast search
|
|
360
|
+
- **1536**: Balance of quality and speed
|
|
361
|
+
- **3072**: Highest quality, slowest
|
|
362
|
+
|
|
363
|
+
**Recommendation**: Use `openrouter` with 768 dimensions for best performance.
|
|
364
|
+
|
|
365
|
+
## SEAL Encryption
|
|
366
|
+
|
|
367
|
+
Encryption is **enabled by default** in v0.8.0+. All memory content is automatically encrypted using SEAL (Secure Encrypted Access Layer).
|
|
200
368
|
|
|
201
|
-
|
|
369
|
+
### How It Works
|
|
202
370
|
|
|
203
|
-
|
|
371
|
+
1. **Identity-based**: Uses Sui address as encryption identity
|
|
372
|
+
2. **Threshold security**: Requires M of N key servers (default: 2 of 2)
|
|
373
|
+
3. **Zero gas for decryption**: No blockchain transactions required
|
|
374
|
+
4. **Privacy-preserving**: Content never exposed on-chain
|
|
375
|
+
|
|
376
|
+
### Default Encryption (Recommended)
|
|
204
377
|
|
|
205
378
|
```typescript
|
|
206
379
|
const pdw = new SimplePDWClient({
|
|
207
380
|
signer: keypair,
|
|
208
381
|
network: 'testnet',
|
|
209
382
|
embedding: { provider: 'openrouter', apiKey: 'key' }
|
|
210
|
-
// Encryption automatically enabled
|
|
383
|
+
// Encryption automatically enabled!
|
|
211
384
|
});
|
|
212
385
|
|
|
213
|
-
// Memories
|
|
386
|
+
// Memories encrypted on upload, decrypted on retrieval
|
|
214
387
|
await pdw.memory.create('My private data');
|
|
215
388
|
```
|
|
216
389
|
|
|
217
|
-
|
|
390
|
+
### Disabling Encryption (Development Only)
|
|
218
391
|
|
|
219
392
|
```typescript
|
|
220
393
|
const pdw = new SimplePDWClient({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
// Encryption configuration (optional)
|
|
226
|
-
encryption: {
|
|
227
|
-
enabled: true, // Default: true
|
|
228
|
-
keyServers: [ // Default: testnet key servers
|
|
229
|
-
'0x73d05d62c18d9374e3ea529e8e0ed6161da1a141a94d3f76ae3fe4e99356db75',
|
|
230
|
-
'0xf5d14a81a982144ae441cd7d64b09027f116a468bd36e7eca494f750591623c8'
|
|
231
|
-
],
|
|
232
|
-
threshold: 2, // Default: 2 (M of N key servers required)
|
|
233
|
-
accessRegistryId: '0x...' // Default: testnet registry
|
|
394
|
+
// ...
|
|
395
|
+
features: {
|
|
396
|
+
enableEncryption: false // Stores content in plaintext!
|
|
234
397
|
}
|
|
235
398
|
});
|
|
236
399
|
```
|
|
237
400
|
|
|
238
|
-
|
|
401
|
+
## Server-Side RAG
|
|
239
402
|
|
|
240
|
-
|
|
241
|
-
# Disable encryption (not recommended for production)
|
|
242
|
-
ENABLE_ENCRYPTION=false
|
|
403
|
+
For server-side applications with RAG (Retrieval-Augmented Generation), content needs to be stored in the local index even when encrypted.
|
|
243
404
|
|
|
244
|
-
|
|
245
|
-
SEAL_KEY_SERVERS=0xKEY1,0xKEY2,0xKEY3
|
|
405
|
+
### Configuration
|
|
246
406
|
|
|
247
|
-
|
|
248
|
-
SEAL_THRESHOLD=2
|
|
407
|
+
When indexing memories server-side, use `forceStoreContent: true`:
|
|
249
408
|
|
|
250
|
-
|
|
251
|
-
|
|
409
|
+
```typescript
|
|
410
|
+
await pdw.index.add(walletAddress, vectorId, embedding, {
|
|
411
|
+
content: plaintextContent,
|
|
412
|
+
blobId: blobId,
|
|
413
|
+
isEncrypted: true,
|
|
414
|
+
forceStoreContent: true // Store content for RAG even when encrypted
|
|
415
|
+
});
|
|
252
416
|
```
|
|
253
417
|
|
|
254
|
-
|
|
418
|
+
### API Route Example
|
|
255
419
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
420
|
+
```typescript
|
|
421
|
+
// /api/memory/index/route.ts
|
|
422
|
+
export async function POST(req: Request) {
|
|
423
|
+
const { walletAddress, memoryId, content, embedding, blobId } = await req.json();
|
|
424
|
+
|
|
425
|
+
const pdw = await getReadOnlyPDWClient(walletAddress);
|
|
426
|
+
|
|
427
|
+
await pdw.index.add(walletAddress, vectorId, embedding, {
|
|
428
|
+
content,
|
|
429
|
+
blobId,
|
|
430
|
+
isEncrypted: true,
|
|
431
|
+
forceStoreContent: true // Enable RAG for encrypted memories
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
```
|
|
261
435
|
|
|
262
|
-
|
|
436
|
+
### Chat API with Memory Search
|
|
263
437
|
|
|
264
|
-
|
|
438
|
+
```typescript
|
|
439
|
+
// /api/chat/route.ts
|
|
440
|
+
export async function POST(req: Request) {
|
|
441
|
+
const { messages, walletAddress } = await req.json();
|
|
442
|
+
const pdw = await getReadOnlyPDWClient(walletAddress);
|
|
443
|
+
|
|
444
|
+
// Search memories for context
|
|
445
|
+
const memories = await pdw.memory.search(userMessage, {
|
|
446
|
+
limit: 10,
|
|
447
|
+
threshold: 0.3,
|
|
448
|
+
includeContent: true
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Build prompt with memory context
|
|
452
|
+
const systemPrompt = `
|
|
453
|
+
User's memories:
|
|
454
|
+
${memories.map(m => m.content).join('\n')}
|
|
455
|
+
`;
|
|
456
|
+
|
|
457
|
+
// Call LLM with context
|
|
458
|
+
return streamText({ model, messages, system: systemPrompt });
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Vector Search (HNSW)
|
|
463
|
+
|
|
464
|
+
The SDK uses HNSW for fast approximate nearest neighbor search:
|
|
465
|
+
|
|
466
|
+
| Implementation | Environment | Performance |
|
|
467
|
+
|----------------|-------------|-------------|
|
|
468
|
+
| `hnswlib-node` | Node.js | **Fastest** (native C++) |
|
|
469
|
+
| `hnswlib-wasm` | Browser + Node.js | Good (fallback) |
|
|
470
|
+
|
|
471
|
+
The SDK auto-detects and uses the best available implementation.
|
|
472
|
+
|
|
473
|
+
### For Best Performance in Node.js
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
# Requires C++ build tools
|
|
477
|
+
npm install hnswlib-node
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
<details>
|
|
481
|
+
<summary>Build tools installation</summary>
|
|
482
|
+
|
|
483
|
+
| Platform | Command |
|
|
484
|
+
|----------|---------|
|
|
485
|
+
| Windows | Install [VS Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) with C++ workload |
|
|
486
|
+
| macOS | `xcode-select --install` |
|
|
487
|
+
| Linux | `sudo apt-get install build-essential python3` |
|
|
488
|
+
|
|
489
|
+
</details>
|
|
490
|
+
|
|
491
|
+
## Index Rebuild
|
|
492
|
+
|
|
493
|
+
When users log in on a new device or the local index is lost, rebuild from blockchain:
|
|
265
494
|
|
|
266
495
|
```typescript
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
496
|
+
import { rebuildIndexNode, hasExistingIndexNode } from '@cmdoss/memwal-sdk';
|
|
497
|
+
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
|
|
498
|
+
|
|
499
|
+
const client = new SuiClient({ url: getFullnodeUrl('testnet') });
|
|
500
|
+
|
|
501
|
+
// Check if index exists
|
|
502
|
+
const hasIndex = await hasExistingIndexNode(userAddress);
|
|
503
|
+
|
|
504
|
+
if (!hasIndex) {
|
|
505
|
+
// Rebuild from blockchain + Walrus
|
|
506
|
+
const result = await rebuildIndexNode({
|
|
507
|
+
userAddress,
|
|
508
|
+
client,
|
|
509
|
+
packageId: process.env.PACKAGE_ID!,
|
|
510
|
+
network: 'testnet',
|
|
511
|
+
force: false, // Set true to force rebuild
|
|
512
|
+
fetchConcurrency: 10, // Parallel blob fetches
|
|
513
|
+
onProgress: (current, total, status) => {
|
|
514
|
+
console.log(`${current}/${total}: ${status}`);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
console.log(`Indexed ${result.indexedMemories}/${result.totalMemories} memories`);
|
|
519
|
+
}
|
|
275
520
|
```
|
|
276
521
|
|
|
277
|
-
|
|
522
|
+
## Exports
|
|
278
523
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
524
|
+
```typescript
|
|
525
|
+
// Main exports
|
|
526
|
+
import { SimplePDWClient } from '@cmdoss/memwal-sdk';
|
|
527
|
+
|
|
528
|
+
// Browser-safe exports
|
|
529
|
+
import { SimplePDWClient, DappKitSigner } from '@cmdoss/memwal-sdk/browser';
|
|
530
|
+
|
|
531
|
+
// React hooks
|
|
532
|
+
import { usePDWClient, useMemory } from '@cmdoss/memwal-sdk/hooks';
|
|
285
533
|
|
|
286
|
-
|
|
534
|
+
// Services (advanced)
|
|
535
|
+
import { EmbeddingService, MemoryIndexService } from '@cmdoss/memwal-sdk/services';
|
|
536
|
+
|
|
537
|
+
// LangChain integration
|
|
538
|
+
import { PDWVectorStore } from '@cmdoss/memwal-sdk/langchain';
|
|
539
|
+
|
|
540
|
+
// Vercel AI SDK integration
|
|
541
|
+
import { createPDWTool } from '@cmdoss/memwal-sdk/ai-sdk';
|
|
542
|
+
|
|
543
|
+
// Node.js utilities
|
|
544
|
+
import { rebuildIndexNode, hasExistingIndexNode, clearIndexNode } from '@cmdoss/memwal-sdk';
|
|
545
|
+
```
|
|
287
546
|
|
|
288
547
|
## Benchmarks
|
|
289
548
|
|
|
290
|
-
Tested on localhost with
|
|
549
|
+
Tested on localhost with encryption enabled:
|
|
291
550
|
|
|
292
551
|
| Operation | Time | Description |
|
|
293
552
|
|-----------|------|-------------|
|
|
294
|
-
|
|
|
295
|
-
| Create Memory | ~2.
|
|
296
|
-
| AI Classification | ~
|
|
297
|
-
| Batch Upload (
|
|
298
|
-
| Blockchain Query | ~
|
|
299
|
-
|
|
300
|
-
**Average query time: ~2.3s** (with OpenRouter API latency included)
|
|
553
|
+
| Memory Search | ~0.5s | Semantic search (local HNSW) |
|
|
554
|
+
| Create Memory | ~2.5s | Classify + embed + encrypt + upload + index |
|
|
555
|
+
| AI Classification | ~0.8s | Categorize content |
|
|
556
|
+
| Batch Upload (5 items) | ~3s | Quilt batching with encryption |
|
|
557
|
+
| Blockchain Query | ~0.3s | List memories from Sui |
|
|
301
558
|
|
|
302
559
|
## Documentation
|
|
303
560
|
|