@merklevault/core
v0.1.1
Published
MerkleVault SDK — Coffre-fort chiffre sur IPFS, utilisable comme librairie Node.js
Maintainers
Readme
@merklevault/core
SDK Node.js pour MerkleVault — coffre-fort chiffré sur IPFS avec synchronisation cloud.
Fonctionnalités
- Chiffrement E2E : XChaCha20-Poly1305 + Argon2id
- Stockage IPFS local via Kubo
- Arborescence fichiers/dossiers avec versioning
- Recherche plein texte (FTS5)
- Synchronisation cloud Pinata (optionnelle)
- Récupération par phrase BIP39 (24 mots)
- Auto-lock configurable
- Système d'événements (EventEmitter)
Prérequis
- Node.js >= 18
- Kubo (go-ipfs) installé ou binaire accessible
- SQLite3 natif (
better-sqlite3en peer dependency)
Installation
npm install @merklevault/core better-sqlite3Démarrage rapide
import { MerkleVault } from '@merklevault/core';
// 1. Créer une instance
const vault = new MerkleVault({
dataDir: './my-vault-data',
kuboBinaryPath: '/usr/local/bin/ipfs', // optionnel
kuboApiPort: 5101, // optionnel
});
// 2. Démarrer (lance Kubo + DB)
await vault.start();
// 3. Créer un vault (première fois uniquement)
const { mnemonic } = await vault.create('MonMotDePasse123');
console.log('Phrase de récupération :', mnemonic);
// ⚠️ Sauvegarder cette phrase — elle ne sera plus affichée !
// 4. Ajouter un fichier
const result = await vault.addFile(Buffer.from('Hello MerkleVault'), {
name: 'hello.txt',
});
console.log('CID IPFS :', result.cid);
// 5. Lire un fichier
const file = await vault.getFile(result.node.id);
console.log(file.data.toString()); // "Hello MerkleVault"
// 6. Arrêter proprement
await vault.stop();API Reference
Constructeur
new MerkleVault(options: MerkleVaultOptions)| Option | Type | Défaut | Description |
|--------|------|--------|-------------|
| dataDir | string | requis | Dossier de données du vault |
| kuboBinaryPath | string | auto-détecté | Chemin vers le binaire Kubo |
| kuboApiPort | number | 5101 | Port API Kubo |
| autoLockMs | number | 900000 (15 min) | Délai d'auto-lock |
| disableAutoLock | boolean | false | Désactiver l'auto-lock |
Lifecycle
await vault.start() // Démarre Kubo + DB + SyncProcessor
await vault.stop() // Arrêt propreGestion du Vault
// Créer un vault (première fois)
const { mnemonic } = await vault.create(password);
// Déverrouiller / verrouiller
vault.unlock(password);
vault.lock();
// État
vault.isUnlocked(); // boolean
vault.getVaultInfo(); // { initialized, unlocked }
// Récupération via BIP39
await vault.recover(mnemonic, newPassword);
// Changer le mot de passe
await vault.changePassword(oldPassword, newPassword);Fichiers & Dossiers
// Ajouter un fichier depuis un Buffer
const result = await vault.addFile(buffer, { name: 'doc.pdf', parentId: folderId });
// Ajouter depuis un chemin disque
const result = await vault.addFileFromPath('/path/to/file.pdf');
// Récupérer un fichier (déchiffré)
const { data, cid, size } = await vault.getFile(nodeId);
// Créer un dossier
const folder = vault.createFolder('Photos', parentId);
// Navigation
const listing = vault.listFolder(parentId); // { node, children }
const node = vault.getNode(nodeId); // FileNode | null
const path = vault.getNodePath(nodeId); // FileNode[] (breadcrumb)
const root = vault.getRootNode(); // FileNode
// Modification
vault.rename(nodeId, 'nouveau-nom.pdf');
vault.move(nodeId, newParentId);
// Suppression / restauration (soft delete)
await vault.delete(nodeId);
vault.restore(nodeId);
const trash = vault.listTrash();
// Versioning
const versions = vault.getVersions(nodeId); // FileVersion[]
// Recherche plein texte
const results = vault.search('rapport 2024'); // FileNode[]Synchronisation Cloud (Pinata)
// Configurer Pinata
const online = await vault.configureCloud({
jwt: 'eyJ...',
gateway: 'https://my-gateway.mypinata.cloud',
});
// Activer / désactiver
vault.toggleCloud(true);
// État
vault.getCloudConfig(); // { provider, active, hasCredentials, gateway }
vault.getSyncStatus(); // { total, synced, pending, errors, provider }Événements
MerkleVault étend EventEmitter. Écoutez des événements individuels ou tous via * :
// Événement spécifique
vault.on('file:added', (event) => {
console.log('Fichier ajouté :', event.data);
});
// Tous les événements
vault.on('*', (event) => {
console.log(`[${event.type}]`, event.data);
});Événements disponibles :
| Événement | Description |
|-----------|-------------|
| vault:created | Vault créé |
| vault:unlocked | Vault déverrouillé |
| vault:locked | Vault verrouillé (manuel ou auto-lock) |
| file:added | Fichier ajouté |
| file:deleted | Fichier supprimé |
| file:renamed | Fichier renommé |
| file:moved | Fichier déplacé |
| folder:created | Dossier créé |
| sync:started | Sync Pinata démarré |
| sync:progress | Progression de sync |
| sync:complete | Sync terminé |
| sync:error | Erreur de sync |
| cloud:configured | Cloud configuré |
| cloud:toggled | Cloud activé/désactivé |
| kubo:ready | Kubo IPFS prêt |
| kubo:crash | Kubo IPFS crashé |
| error | Erreur générique |
Statut global
const status = await vault.getStatus();
// {
// kuboReady, kuboPid, rootNode,
// ipfsOnline, vaultInitialized, vaultUnlocked,
// cloudProvider, cloudActive
// }Types exportés
import type {
MerkleVaultOptions,
FileNode,
FileVersion,
VaultInfo,
CreateVaultResult,
CloudProvider,
PinataCredentials,
CloudConfig,
SyncStatus,
SyncStatusValue,
AddFileResult,
GetFileResult,
FolderListing,
DaemonStatus,
VaultEventType,
VaultEvent,
} from '@merklevault/core';Architecture
@merklevault/core
├── MerkleVault (facade)
│ ├── KuboManager — Gestion du noeud IPFS local
│ ├── Database — SQLite + FTS5 (better-sqlite3)
│ ├── StorageRouter — Routage local/cloud
│ │ ├── KuboContentStore — Stockage IPFS local
│ │ └── PinataContentStore — Stockage cloud Pinata
│ ├── CryptoModule — XChaCha20 + Argon2id + BIP39
│ └── SyncQueueProcessor — File de sync automatiqueSécurité
- Les fichiers sont chiffrés côté client avant d'être stockés sur IPFS
- La master key est dérivée du mot de passe via Argon2id (résistant aux GPU)
- La phrase BIP39 permet la récupération sans le mot de passe
- Auto-lock après 15 minutes d'inactivité (configurable)
- La master key est mise à zéro en mémoire lors du lock
Licence
MIT — El Mehdi Iddouch
