Introduction
Getting started with the Enbox SDK — decentralized identity, data, and authentication for TypeScript.
What is Enbox?
Enbox is a TypeScript SDK for building applications where users own their data. Instead of storing user data in your database, Enbox gives each user a Decentralized Web Node (DWN) — a personal data vault they control. Your app reads and writes to it with their permission.
The SDK handles:
- Identity — Decentralized Identifiers (DIDs) that users own, not your server
- Storage — Protocol-defined records in personal DWN vaults, synced across devices
- Authentication — Passwordless auth with vault encryption, recovery phrases, and multi-identity
- Encryption — End-to-end encrypted records with ECDH key agreement
Installation
bun add @enbox/apiQuick start
1. Define a protocol
A protocol describes the data your app works with — its schema, structure, and access rules.
import { defineProtocol, recordCodecs } from '@enbox/api';
const TaskDefinition = {
protocol: 'https://example.com/tasks',
published: true,
types: {
task: {
schema: 'https://example.com/schemas/task',
dataFormats: ['application/json'],
},
},
structure: {
task: {},
},
} as const;
const TaskProtocol = defineProtocol(TaskDefinition, {
task: recordCodecs.json<{ title: string; done: boolean }>(),
});2. Connect and use
import { createConnectionStore, defineApplicationManifest } from '@enbox/api';
const application = defineApplicationManifest({
protocols: [TaskProtocol],
} as const);
const store = createConnectionStore({ application });
let snapshot = await store.initialize();
if (snapshot.phase === 'disconnected') {
snapshot = await store.connectVault({ createIdentity: true });
}
if (snapshot.phase !== 'connected') {
throw snapshot.error ?? new Error('Connection was not established.');
}
const tasks = snapshot.enbox.using(TaskProtocol);The connection store owns session restore, connection, protocol readiness, and
facade replacement for common apps. Read the active API from snapshot.enbox.
Create one store for the application/data path and keep it for the application
lifetime; separate stores intentionally do not coordinate.
3. CRUD operations
// Create
const record = await tasks.records.create('task', {
data: { title: 'Buy milk', done: false },
});
// Read
const task = await record.value(); // { title: 'Buy milk', done: false }
const raw = await record.data.text(); // raw JSON string
const blob = await record.data.blob(); // Blob
const bytes = await record.data.bytes(); // Uint8Array
// Update
await record.update({
data: { title: 'Buy milk', done: true },
});
// Query all tasks
const { records } = await tasks.records.query('task');
for (const r of records) {
console.log(await r.value());
}
// Delete
await record.delete();When the user signs out or the application shuts down, release the lifecycle:
await store.disconnect();
await store.dispose();Packages
| Package | Description |
|---|---|
@enbox/api | High-level SDK — connection lifecycle, typed protocols, records CRUD |
@enbox/browser | Browser entrypoint — app APIs, auth helpers, wallet connect, DWeb utilities |
@enbox/cli | CLI entrypoint — app APIs, auth helpers, relay/PIN wallet connect |
@enbox/auth | Authentication — connect, lock, disconnect, multi-identity |
@enbox/dwn-server | Self-hostable DWN server with PostgreSQL, MySQL, SQLite |
@enbox/agent | Low-level agent runtime for DID and DWN operations |
@enbox/protocols | Protocol definitions and type-safe schema helpers |
@enbox/dids | DID creation, resolution, and key management |
@enbox/crypto | Cryptographic primitives (JOSE, key wrapping, ECDH) |
@enbox/common | Shared utilities (TTL cache, LevelStore) |
@enbox/dwn-sdk-js | Decentralized Web Node protocol engine |
@enbox/dwn-sql-store | SQL storage backends for the DWN |
@enbox/dwn-clients | HTTP and WebSocket DWN transport clients |