Sterister c95824f95f feat(sdk): M-Magic 1-4 — high-level SDK with magic drop-in
Phase A complete: createShade() one-liner with auto-establish, auto-publish,
and auto-replenish.

M-Magic 1-4 rolled into @shade/sdk:
- createShade() factory with config validation and storage resolution
  (memory | sqlite:... | { type: 'postgres', url: ... } | explicit instance)
- Shade class wraps crypto + storage + session manager + transport
- Auto-publish: initialize() automatically registers with the prekey server
- Auto-establish: send() transparently fetches bundles and creates sessions
  on first message to a new peer
- Per-address mutex serializes concurrent sends to prevent ratchet corruption
- BackgroundTasks class for periodic replenishment + opt-in identity rotation
- rotate() rebuilds the transport with the new signing key so subsequent
  signed operations work after rotation
- onMessage() handler API for incoming plaintext

API:
  const shade = await createShade({ prekeyServer, storage });
  await shade.send('bob', 'hello');
  await shade.receive('alice', envelope);
  shade.onMessage((from, msg) => ...);
  await shade.rotate();
  await shade.shutdown();

13 new SDK tests covering: happy path, auto-publish, two-process
conversation, onMessage handlers, concurrent sends, unknown peer,
fingerprint verification, shutdown, manual replenish, auto-replenish
off, rotate, and config validation.

233 tests passing, 0 failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:27:59 +02:00
2026-04-09 20:12:01 +02:00

Shade

End-to-end encryption library implementing the Signal Protocol (X3DH + Double Ratchet) for TypeScript/Bun. Drop into any project — frontend, backend, mobile — to get forward secrecy, post-compromise recovery, and self-healing security.

What you get

  • X3DH initial key agreement (works asynchronously via prekey bundles)
  • Double Ratchet for per-message forward secrecy and post-compromise security
  • Self-authenticated prekey server (Hono, Docker-ready) with rate limiting, metrics, health checks
  • Persistent storage backends: SQLite (zero-config) and PostgreSQL (Drizzle)
  • Identity rotation with grace period for old sessions
  • Safety numbers (Signal-style fingerprints) for out-of-band verification
  • Constant-time comparisons and memory zeroization for hardened operation
  • Binary wire format that's significantly smaller than JSON
  • Crash-safe — sessions survive container restarts, power outages, SIGKILL
  • Live observability — bundled dashboard SPA + embeddable React widgets to see what's happening between every step

Quick start

# In your project
bun add @shade/core @shade/crypto-web @shade/storage-sqlite
import { ShadeSessionManager } from '@shade/core';
import { SubtleCryptoProvider } from '@shade/crypto-web';
import { SQLiteStorage } from '@shade/storage-sqlite';

const crypto = new SubtleCryptoProvider();
const storage = new SQLiteStorage('/data/shade-client.db');

const manager = new ShadeSessionManager(crypto, storage);
await manager.initialize();

// Establish a session with a peer (after fetching their bundle)
await manager.initSessionFromBundle('bob', bobBundle);

// Encrypt
const envelope = await manager.encrypt('bob', 'Hello, encrypted world!');

// Decrypt
const plaintext = await manager.decrypt('alice', incomingEnvelope);

Architecture

                     Shade Prekey Server (Hono)
                              │
              POST /v1/keys/register (signed)
              GET  /v1/keys/bundle/:address
              POST /v1/keys/replenish (signed)
              DELETE /v1/keys/:address (signed)
                              │
        ┌─────────────────────┴─────────────────────┐
        │                                           │
    [Client A]                                  [Client B]
    ShadeSessionManager                         ShadeSessionManager
        │                                           │
        ├──── X3DH ────────────────────────────────►│
        │                                           │
        │◄──── Double Ratchet messages ────────────►│
        │                                           │
    SQLiteStorage / PostgresStorage             SQLiteStorage / PostgresStorage

Packages

Package Purpose
@shade/core Protocol logic (X3DH, Double Ratchet, session manager, errors, events)
@shade/crypto-web SubtleCrypto + @noble/curves provider, in-memory storage
@shade/storage-sqlite Persistent SQLite storage (zero-config, bun:sqlite)
@shade/storage-postgres PostgreSQL storage with Drizzle for shared databases
@shade/server Prekey server (Hono routes, auth, rate limit, health, metrics)
@shade/transport HTTP + WebSocket transport wrappers with auto-encryption
@shade/proto Compact binary wire format (smaller than JSON)
@shade/observer Live debugger backend (snapshot, SSE, dashboard) — see README
@shade/widgets Embeddable React widgets — see README
@shade/dashboard Standalone dashboard SPA bundled into the observer

Security properties

Property Description
Forward secrecy Compromising a key cannot decrypt past messages
Post-compromise security Self-heals after key compromise on next DH ratchet
Authentication Ed25519 identity signatures on prekey server writes
Replay protection ±5 minute timestamp window on signed requests
Constant-time comparisons Timing attacks on identity keys are blocked
Memory zeroization Key material is zeroed after use (best-effort in JS)
Identity verification Safety numbers (60 digits) for out-of-band comparison
Identity rotation 7-day grace period for old sessions during rotation

Documentation

Deployment

For containerized deployment (Docker/Dokploy):

services:
  shade-prekey:
    image: shade-prekey-server:latest
    ports:
      - "3900:3900"
    volumes:
      - shade-data:/data
    environment:
      - SHADE_PREKEY_DB_PATH=/data/shade-prekeys.db
volumes:
  shade-data:

The SQLite database persists to a Docker volume so all keys and prekey bundles survive restarts.

License

MIT

Description
E2EE library implementing Signal Protocol (X3DH + Double Ratchet)
Readme MIT 2.8 MiB
Languages
TypeScript 93.1%
Kotlin 6.7%
Shell 0.1%