@merklevault/core 0.1.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 +256 -0
- package/dist/index.cjs +2065 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +303 -0
- package/dist/index.d.ts +303 -0
- package/dist/index.js +2028 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# @merklevault/core
|
|
2
|
+
|
|
3
|
+
SDK Node.js pour MerkleVault — coffre-fort chiffré sur IPFS avec synchronisation cloud.
|
|
4
|
+
|
|
5
|
+
## Fonctionnalités
|
|
6
|
+
|
|
7
|
+
- Chiffrement E2E : XChaCha20-Poly1305 + Argon2id
|
|
8
|
+
- Stockage IPFS local via Kubo
|
|
9
|
+
- Arborescence fichiers/dossiers avec versioning
|
|
10
|
+
- Recherche plein texte (FTS5)
|
|
11
|
+
- Synchronisation cloud Pinata (optionnelle)
|
|
12
|
+
- Récupération par phrase BIP39 (24 mots)
|
|
13
|
+
- Auto-lock configurable
|
|
14
|
+
- Système d'événements (EventEmitter)
|
|
15
|
+
|
|
16
|
+
## Prérequis
|
|
17
|
+
|
|
18
|
+
- Node.js >= 18
|
|
19
|
+
- Kubo (go-ipfs) installé ou binaire accessible
|
|
20
|
+
- SQLite3 natif (`better-sqlite3` en peer dependency)
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @merklevault/core better-sqlite3
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Démarrage rapide
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { MerkleVault } from '@merklevault/core';
|
|
32
|
+
|
|
33
|
+
// 1. Créer une instance
|
|
34
|
+
const vault = new MerkleVault({
|
|
35
|
+
dataDir: './my-vault-data',
|
|
36
|
+
kuboBinaryPath: '/usr/local/bin/ipfs', // optionnel
|
|
37
|
+
kuboApiPort: 5101, // optionnel
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// 2. Démarrer (lance Kubo + DB)
|
|
41
|
+
await vault.start();
|
|
42
|
+
|
|
43
|
+
// 3. Créer un vault (première fois uniquement)
|
|
44
|
+
const { mnemonic } = await vault.create('MonMotDePasse123');
|
|
45
|
+
console.log('Phrase de récupération :', mnemonic);
|
|
46
|
+
// ⚠️ Sauvegarder cette phrase — elle ne sera plus affichée !
|
|
47
|
+
|
|
48
|
+
// 4. Ajouter un fichier
|
|
49
|
+
const result = await vault.addFile(Buffer.from('Hello MerkleVault'), {
|
|
50
|
+
name: 'hello.txt',
|
|
51
|
+
});
|
|
52
|
+
console.log('CID IPFS :', result.cid);
|
|
53
|
+
|
|
54
|
+
// 5. Lire un fichier
|
|
55
|
+
const file = await vault.getFile(result.node.id);
|
|
56
|
+
console.log(file.data.toString()); // "Hello MerkleVault"
|
|
57
|
+
|
|
58
|
+
// 6. Arrêter proprement
|
|
59
|
+
await vault.stop();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## API Reference
|
|
63
|
+
|
|
64
|
+
### Constructeur
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
new MerkleVault(options: MerkleVaultOptions)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Option | Type | Défaut | Description |
|
|
71
|
+
|--------|------|--------|-------------|
|
|
72
|
+
| `dataDir` | `string` | *requis* | Dossier de données du vault |
|
|
73
|
+
| `kuboBinaryPath` | `string` | auto-détecté | Chemin vers le binaire Kubo |
|
|
74
|
+
| `kuboApiPort` | `number` | `5101` | Port API Kubo |
|
|
75
|
+
| `autoLockMs` | `number` | `900000` (15 min) | Délai d'auto-lock |
|
|
76
|
+
| `disableAutoLock` | `boolean` | `false` | Désactiver l'auto-lock |
|
|
77
|
+
|
|
78
|
+
### Lifecycle
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
await vault.start() // Démarre Kubo + DB + SyncProcessor
|
|
82
|
+
await vault.stop() // Arrêt propre
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Gestion du Vault
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Créer un vault (première fois)
|
|
89
|
+
const { mnemonic } = await vault.create(password);
|
|
90
|
+
|
|
91
|
+
// Déverrouiller / verrouiller
|
|
92
|
+
vault.unlock(password);
|
|
93
|
+
vault.lock();
|
|
94
|
+
|
|
95
|
+
// État
|
|
96
|
+
vault.isUnlocked(); // boolean
|
|
97
|
+
vault.getVaultInfo(); // { initialized, unlocked }
|
|
98
|
+
|
|
99
|
+
// Récupération via BIP39
|
|
100
|
+
await vault.recover(mnemonic, newPassword);
|
|
101
|
+
|
|
102
|
+
// Changer le mot de passe
|
|
103
|
+
await vault.changePassword(oldPassword, newPassword);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Fichiers & Dossiers
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Ajouter un fichier depuis un Buffer
|
|
110
|
+
const result = await vault.addFile(buffer, { name: 'doc.pdf', parentId: folderId });
|
|
111
|
+
|
|
112
|
+
// Ajouter depuis un chemin disque
|
|
113
|
+
const result = await vault.addFileFromPath('/path/to/file.pdf');
|
|
114
|
+
|
|
115
|
+
// Récupérer un fichier (déchiffré)
|
|
116
|
+
const { data, cid, size } = await vault.getFile(nodeId);
|
|
117
|
+
|
|
118
|
+
// Créer un dossier
|
|
119
|
+
const folder = vault.createFolder('Photos', parentId);
|
|
120
|
+
|
|
121
|
+
// Navigation
|
|
122
|
+
const listing = vault.listFolder(parentId); // { node, children }
|
|
123
|
+
const node = vault.getNode(nodeId); // FileNode | null
|
|
124
|
+
const path = vault.getNodePath(nodeId); // FileNode[] (breadcrumb)
|
|
125
|
+
const root = vault.getRootNode(); // FileNode
|
|
126
|
+
|
|
127
|
+
// Modification
|
|
128
|
+
vault.rename(nodeId, 'nouveau-nom.pdf');
|
|
129
|
+
vault.move(nodeId, newParentId);
|
|
130
|
+
|
|
131
|
+
// Suppression / restauration (soft delete)
|
|
132
|
+
await vault.delete(nodeId);
|
|
133
|
+
vault.restore(nodeId);
|
|
134
|
+
const trash = vault.listTrash();
|
|
135
|
+
|
|
136
|
+
// Versioning
|
|
137
|
+
const versions = vault.getVersions(nodeId); // FileVersion[]
|
|
138
|
+
|
|
139
|
+
// Recherche plein texte
|
|
140
|
+
const results = vault.search('rapport 2024'); // FileNode[]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Synchronisation Cloud (Pinata)
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Configurer Pinata
|
|
147
|
+
const online = await vault.configureCloud({
|
|
148
|
+
jwt: 'eyJ...',
|
|
149
|
+
gateway: 'https://my-gateway.mypinata.cloud',
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Activer / désactiver
|
|
153
|
+
vault.toggleCloud(true);
|
|
154
|
+
|
|
155
|
+
// État
|
|
156
|
+
vault.getCloudConfig(); // { provider, active, hasCredentials, gateway }
|
|
157
|
+
vault.getSyncStatus(); // { total, synced, pending, errors, provider }
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Événements
|
|
161
|
+
|
|
162
|
+
MerkleVault étend `EventEmitter`. Écoutez des événements individuels ou tous via `*` :
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Événement spécifique
|
|
166
|
+
vault.on('file:added', (event) => {
|
|
167
|
+
console.log('Fichier ajouté :', event.data);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Tous les événements
|
|
171
|
+
vault.on('*', (event) => {
|
|
172
|
+
console.log(`[${event.type}]`, event.data);
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Événements disponibles :
|
|
177
|
+
|
|
178
|
+
| Événement | Description |
|
|
179
|
+
|-----------|-------------|
|
|
180
|
+
| `vault:created` | Vault créé |
|
|
181
|
+
| `vault:unlocked` | Vault déverrouillé |
|
|
182
|
+
| `vault:locked` | Vault verrouillé (manuel ou auto-lock) |
|
|
183
|
+
| `file:added` | Fichier ajouté |
|
|
184
|
+
| `file:deleted` | Fichier supprimé |
|
|
185
|
+
| `file:renamed` | Fichier renommé |
|
|
186
|
+
| `file:moved` | Fichier déplacé |
|
|
187
|
+
| `folder:created` | Dossier créé |
|
|
188
|
+
| `sync:started` | Sync Pinata démarré |
|
|
189
|
+
| `sync:progress` | Progression de sync |
|
|
190
|
+
| `sync:complete` | Sync terminé |
|
|
191
|
+
| `sync:error` | Erreur de sync |
|
|
192
|
+
| `cloud:configured` | Cloud configuré |
|
|
193
|
+
| `cloud:toggled` | Cloud activé/désactivé |
|
|
194
|
+
| `kubo:ready` | Kubo IPFS prêt |
|
|
195
|
+
| `kubo:crash` | Kubo IPFS crashé |
|
|
196
|
+
| `error` | Erreur générique |
|
|
197
|
+
|
|
198
|
+
### Statut global
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const status = await vault.getStatus();
|
|
202
|
+
// {
|
|
203
|
+
// kuboReady, kuboPid, rootNode,
|
|
204
|
+
// ipfsOnline, vaultInitialized, vaultUnlocked,
|
|
205
|
+
// cloudProvider, cloudActive
|
|
206
|
+
// }
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Types exportés
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import type {
|
|
213
|
+
MerkleVaultOptions,
|
|
214
|
+
FileNode,
|
|
215
|
+
FileVersion,
|
|
216
|
+
VaultInfo,
|
|
217
|
+
CreateVaultResult,
|
|
218
|
+
CloudProvider,
|
|
219
|
+
PinataCredentials,
|
|
220
|
+
CloudConfig,
|
|
221
|
+
SyncStatus,
|
|
222
|
+
SyncStatusValue,
|
|
223
|
+
AddFileResult,
|
|
224
|
+
GetFileResult,
|
|
225
|
+
FolderListing,
|
|
226
|
+
DaemonStatus,
|
|
227
|
+
VaultEventType,
|
|
228
|
+
VaultEvent,
|
|
229
|
+
} from '@merklevault/core';
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Architecture
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
@merklevault/core
|
|
236
|
+
├── MerkleVault (facade)
|
|
237
|
+
│ ├── KuboManager — Gestion du noeud IPFS local
|
|
238
|
+
│ ├── Database — SQLite + FTS5 (better-sqlite3)
|
|
239
|
+
│ ├── StorageRouter — Routage local/cloud
|
|
240
|
+
│ │ ├── KuboContentStore — Stockage IPFS local
|
|
241
|
+
│ │ └── PinataContentStore — Stockage cloud Pinata
|
|
242
|
+
│ ├── CryptoModule — XChaCha20 + Argon2id + BIP39
|
|
243
|
+
│ └── SyncQueueProcessor — File de sync automatique
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Sécurité
|
|
247
|
+
|
|
248
|
+
- Les fichiers sont chiffrés côté client avant d'être stockés sur IPFS
|
|
249
|
+
- La master key est dérivée du mot de passe via Argon2id (résistant aux GPU)
|
|
250
|
+
- La phrase BIP39 permet la récupération sans le mot de passe
|
|
251
|
+
- Auto-lock après 15 minutes d'inactivité (configurable)
|
|
252
|
+
- La master key est mise à zéro en mémoire lors du lock
|
|
253
|
+
|
|
254
|
+
## Licence
|
|
255
|
+
|
|
256
|
+
MIT — Chaymae Lougmani
|